scopedvr-map-editor/tests/probe_u5_place_once_render.gd
2026-11-01 19:34:05 +01:00

142 lines
No EOL
5 KiB
GDScript

extends SceneTree
## Beweis-Probe (Karte t_5e3e97c9, WEGWERF — nicht Teil der Suite):
## U5 Platzieren: Bildfolge VORHER (Ghost in der Hand) → GESETZT (Marker da,
## Werkzeug aus) → AUSGEWÄHLT (Auswahl-Markierung + Inspektor-Tab sichtbar).
## Der Platzier-Pfad ist der ECHTE: interaction._place_object (gleicher Pfad
## wie ein Linksklick, Karten-Regel: kein simuliertes Umfeld).
## Aufruf: xvfb-run -a godot4 --path . --rendering-driver opengl3 \
## -s res://tests/probe_u5_place_once_render.gd
func _initialize() -> void:
_run.call_deferred()
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()])
## Rechts-Tabs: den Tab mit „Inspektor“ nach vorn holen (Fallback „Baum“),
## damit die Auswahl im Beweis-Bild sichtbar wird.
func _show_selection_tab(main: Node) -> String:
var stack: Array = [main]
while not stack.is_empty():
var n: Node = stack.pop_back()
if n is TabContainer:
var tabs := n as TabContainer
for i in tabs.get_tab_count():
var titel := tabs.get_tab_title(i)
if titel.contains("Auswahl") or titel.contains("Baum"):
tabs.current_tab = i
return titel
stack.append_array(n.get_children())
return ""
## „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())
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
# „Modelle fehlen“-Hinweis schließen (Beweis-Bilder sollen die Karte zeigen).
await _dismiss_dialogs()
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED)
DisplayServer.window_set_size(Vector2i(2328, 1310))
await process_frame
DisplayServer.window_set_size(Vector2i(2328, 1310))
var interaction = main.get("interaction")
var oid := ""
var lib: Dictionary = main.manifest.get("objects", {})
for key in lib:
oid = str(key)
break
if oid == "":
print("PROBE_U5_FAIL: kein Manifest-Objekt")
quit(1)
return
main.call("_set_tool_mode", "objects")
interaction.call("start_placement", oid)
await process_frame
await process_frame
var cam = main.get("camera")
if cam != null:
cam.set("distance", 22.0)
cam.call("focus_on", Vector3(0.0, 0.0, 0.0))
await process_frame
await process_frame
# Cursor übers Karte-Zentrum → Ghost sichtbar parken (echter Ghost-Pfad).
var vp: SubViewport = null
var stack: Array = [main]
while not stack.is_empty():
var n: Node = stack.pop_back()
if n is SubViewportContainer:
vp = n.get_child(0) as SubViewport
break
stack.append_array(n.get_children())
if vp == null:
print("PROBE_U5_FAIL: kein SubViewport")
quit(1)
return
var mm := InputEventMouseMotion.new()
mm.position = (vp.size as Vector2) * 0.5
mm.global_position = mm.position
vp.push_input(mm)
await process_frame
await process_frame
var dir := "/tmp/u5_beweise"
DirAccess.make_dir_recursive_absolute(dir)
await _shot(dir + "/u5_1_vorher_ghost.png")
print("PRUEF vorher: placing=%s objects=%s" % [
str(bool(interaction.get("placing"))),
str((main.doc["objects"] as Array).size())])
# ECHTER Platzier-Pfad (wie Linksklick, ohne Shift → Einmal-Modus).
interaction.call("_place_object", mm.position)
await process_frame
await process_frame
await _shot(dir + "/u5_2_gesetzt.png")
var placed := (main.doc["objects"] as Array).size()
var builder = main.get("view_builder")
var sel_mat: StandardMaterial3D = builder.get("_select_mat")
var marker = null
if placed > 0:
marker = builder.object_markers[placed - 1].get_child(0)
var hat_auswahl: bool = marker != null and marker.material_override == sel_mat
var insp = main.get("inspector")
var head_txt := ""
if insp != null and insp.get("_head") != null:
head_txt = str(insp.get("_head").text)
print("PRUEF gesetzt: placing=%s objects=%s selected_index=%s marker_auswahl=%s inspektor='%s'" % [
str(bool(interaction.get("placing"))), str(placed),
str(interaction.get("selected_index")), str(hat_auswahl), head_txt])
print("PRUEF status='%s'" % str(main.status_label.text))
# Bild 3: Auswahl im UI sichtbar — Inspektor-Tab nach vorn.
var tab := _show_selection_tab(main)
await process_frame
await process_frame
print("PRUEF tab='%s'" % tab)
await _shot(dir + "/u5_3_ausgewaehlt_inspektor.png")
var ok := not bool(interaction.get("placing")) \
and placed == 1 \
and int(interaction.get("selected_index")) == 0 \
and hat_auswahl \
and str(main.status_label.text).contains("ausgewählt")
print("PROBE_U5_%s" % ("OK" if ok else "FAIL"))
quit(0 if ok else 1)