extends SceneTree ## Beweis-Probe (Karte t_bceb0965, WEGWERF — nicht Teil der Suite): ## Mehrfachauswahl mit 3 Objekten — gemeinsames Verschieben via Inspektor ## (relativ: Abstände bleiben), Zahlen vor/nach, EIN Undo stellt ALLE her, ## abschließend ein PNG mit den 3 markierten Objekten nach dem Verschieben. ## Aufruf: xvfb-run -a godot4 --path . --rendering-driver opengl3 \ ## -s res://tests/probe_multi_move.gd (PROBE_PNG = Ausgabepfad) func _initialize() -> void: _run.call_deferred() func _pos(obj: Dictionary) -> Array: return obj.get("pos", [0.0, 0.0, 0.0]) func _dist(a: Dictionary, b: Dictionary) -> float: var pa := _pos(a) var pb := _pos(b) return Vector2(float(pa[0]), float(pa[2])).distance_to(Vector2(float(pb[0]), float(pb[2]))) func _run() -> void: var scene: PackedScene = load("res://core/scenes/main.tscn") var main = scene.instantiate() root.add_child(main) await process_frame await process_frame DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED) DisplayServer.window_set_size(Vector2i(2328, 1310)) # Drei Objekte im Dreieck (verschiedene X/Z → Abstände sind eindeutig). var objs: Array = main.doc["objects"] objs.append({"id": "barrel_001", "pos": [8.0, 0.0, 8.0], "scale": 1.5, "rot_y_deg": 30.0}) objs.append({"id": "box_001", "pos": [14.0, 0.0, 6.0], "scale": 1.0, "rot_y_deg": 0.0}) objs.append({"id": "wall_001", "pos": [11.0, 0.0, 13.0], "scale": 1.0, "rot_y_deg": 0.0}) main.call("_after_structure_change") main.history.clear() main.interaction.call("select_many", [0, 1, 2]) await process_frame var cam = main.get("camera") if cam != null: cam.call("focus_on", Vector3(11.0, 0.0, 9.5)) cam.set("distance", 34.0) # ---- Zahlen VORHER ---- var d01_vor := _dist(objs[0], objs[1]) var d02_vor := _dist(objs[0], objs[2]) var d12_vor := _dist(objs[1], objs[2]) print("PROBE_VOR pos0=%s pos1=%s pos2=%s" % [_pos(objs[0]), _pos(objs[1]), _pos(objs[2])]) print("PROBE_VOR Abstaende: 0-1=%.3f 0-2=%.3f 1-2=%.3f" % [d01_vor, d02_vor, d12_vor]) # ---- Gemeinsames Verschieben: Inspektor pos_x tippen (Anker → 12.0) ---- var insp = main.get("inspector") var w = insp.widget("pos_x") w.edit.text = "12.0" w.edit.text_submitted.emit("12.0") await process_frame var d01_nach := _dist(objs[0], objs[1]) var d02_nach := _dist(objs[0], objs[2]) var d12_nach := _dist(objs[1], objs[2]) print("PROBE_NACH pos0=%s pos1=%s pos2=%s" % [_pos(objs[0]), _pos(objs[1]), _pos(objs[2])]) print("PROBE_NACH Abstaende: 0-1=%.3f 0-2=%.3f 1-2=%.3f" % [d01_nach, d02_nach, d12_nach]) var ok_abst := absf(d01_nach - d01_vor) < 0.001 \ and absf(d02_nach - d02_vor) < 0.001 \ and absf(d12_nach - d12_vor) < 0.001 print("PROBE_ABSTAENDE_ERHALTEN %s" % ("OK" if ok_abst else "FAIL")) # ---- EIN Undo stellt ALLE drei her ---- main.call("_do_undo") await process_frame var p0_undo := _pos(objs[0]) var p1_undo := _pos(objs[1]) var p2_undo := _pos(objs[2]) var ok_undo := str(p0_undo) == "8, 0, 8" or (absf(float(p0_undo[0]) - 8.0) < 0.001 \ and absf(float(p0_undo[2]) - 8.0) < 0.001) var ok_undo1 := absf(float(p1_undo[0]) - 14.0) < 0.001 and absf(float(p1_undo[2]) - 6.0) < 0.001 var ok_undo2 := absf(float(p2_undo[0]) - 11.0) < 0.001 and absf(float(p2_undo[2]) - 13.0) < 0.001 print("PROBE_UNDO pos0=%s pos1=%s pos2=%s" % [p0_undo, p1_undo, p2_undo]) print("PROBE_UNDO_ALLE_ZURUECK %s" % ("OK" if (ok_undo and ok_undo1 and ok_undo2) else "FAIL")) # ---- Zustand für das Bild wiederherstellen: Redo = dieselbe Verschiebung ---- main.call("_do_redo") await process_frame print("PROBE_REDO pos0=%s pos1=%s pos2=%s" % [_pos(objs[0]), _pos(objs[1]), _pos(objs[2])]) # ---- PNG: drei markierte Objekte nach der gemeinsamen Verschiebung ---- for i in 6: await process_frame await RenderingServer.frame_post_draw var img := root.get_texture().get_image() var out := OS.get_environment("PROBE_PNG") if out.is_empty(): out = "/tmp/probe_multi_move.png" img.save_png(out) print("PNG_OK ", out) quit(0)