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

147 lines
5.2 KiB
GDScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

extends SceneTree
## Beweis-Probe (Karte t_639135dd, WEGWERF — nicht Teil der Suite):
## U6 dezente Auswahl — dasselbe Objekt (barrel_001, 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://core/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": "barrel_001", "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)