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

135 lines
5 KiB
GDScript
Raw 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
## WEGWERF-Renderprobe (Karte t_eca890c5, K1b Startansicht = Karten-INHALT) — 3 Bilder 1600×900:
## (a) Map geladen → fit_to_document: INHALT (Kisten+Spawns) im Bild, Kisten gut sichtbar
## (b) MMT auf Objekt + 60 px ziehen → Objekt bleibt unterm Cursor, kein Sprung
## (c) Pos1 → GANZE Karte wieder im Bild (Statuszeile „Pos1: ganze Karte ins Bild.“)
## Ausführen:
## xvfb-run -a godot4 --path . --rendering-driver opengl3 -s res://tests/probe_k1b_render.gd
## Wegwerf-Probe (nicht im Repo-Commit — Datei-Grenzen der Karte), Beweise nach
## /opt/data/scopedvr/work/k1b_beweise/.
var main: Control
var camera: Camera3D
var subvp: SubViewport
var step := 0
func _initialize() -> void:
_run.call_deferred()
func _png(name: String) -> String:
return "/opt/data/scopedvr/work/k1b_beweise/" + name
func _shot(name: String) -> void:
await process_frame
await process_frame
var img := subvp.get_texture().get_image()
img.save_png(_png(name))
print("PROBE_PNG=%s (%dx%d)" % [_png(name), img.get_width(), img.get_height()])
func _find_subvp(node: Node) -> SubViewport:
if node is SubViewport:
return node as SubViewport
for c in node.get_children():
var f := _find_subvp(c)
if f != null:
return f
return null
func _mouse(btn: int, pressed: bool, pos: Vector2) -> void:
var ev := InputEventMouseButton.new()
ev.button_index = btn as MouseButton
ev.pressed = pressed
ev.position = pos
ev.global_position = pos
subvp.push_input(ev)
func _motion(pos: Vector2) -> void:
var ev := InputEventMouseMotion.new()
ev.position = pos
ev.global_position = pos
subvp.push_input(ev)
func _key(code: Key) -> void:
var key := InputEventKey.new()
key.keycode = code
key.physical_keycode = code
key.pressed = true
subvp.push_input(key)
func _in_frustum(p: Vector3) -> bool:
return camera.is_position_in_frustum(p)
func _run() -> void:
var scene: PackedScene = load("res://core/scenes/main.tscn")
main = scene.instantiate()
root.add_child(main)
await process_frame
await process_frame
camera = main.get("camera")
subvp = _find_subvp(main)
var container: SubViewportContainer = subvp.get_parent()
container.stretch = false
subvp.size = Vector2i(1600, 900)
await process_frame
# Gleiche Test-Szene wie die Suite: 2 Kisten + Default-Spawns (1024er Map).
var doc: Dictionary = SvmapDocument.create_new("K1b-Probe", 1024.0, "mittag")
doc["objects"] = [
{"id": "box_001", "pos": [0.0, 0.0, 0.0], "scale": 1.0, "rot_y_deg": 0.0},
{"id": "box_001", "pos": [450.0, 0.0, 450.0], "scale": 1.0, "rot_y_deg": 0.0},
]
main.set("doc", doc)
main.call("_refresh_all")
await process_frame
await process_frame
var builder = main.get("view_builder")
var marker: Node3D = (builder.get("object_markers") as Array)[0]
var center: Vector3 = marker.global_position + Vector3.UP * float(marker.get_meta("half_height", 0.0))
print("ZAHLEN (a) target=", camera.get("target"), " distance=", camera.get("distance"))
print("ZAHLEN (a) Objekt ", center, " → px ", camera.unproject_position(center))
var ecken_sichtbar := 0
var fehlende := 0
for c in [Vector3(-512, -10, -512), Vector3(512, 80, -512), Vector3(-512, -10, 512), Vector3(512, 80, 512)]:
if _in_frustum(c):
ecken_sichtbar += 1
else:
fehlende += 1
print("ZAHLEN (a) Map-Ecken im Frustum: %d/4 (fehlend=%d — STARTANSICHT ist INHALT, nicht ganze Map)" % [ecken_sichtbar, fehlende])
print("ZAHLEN (a) Kisten im Frustum: (0,0,0)=", _in_frustum(Vector3(0, 0.6, 0)),
" (450,0.6,450)=", _in_frustum(Vector3(450, 0.6, 450)))
print("ZAHLEN (a) Status: ", main.status_label.text)
await _shot("k1b_a_startansicht_inhalt.png")
# --- (b) MMT auf Objekt + 60 px ziehen (K1-Prüfung bleibt intakt) --------
var press: Vector2 = camera.unproject_position(center)
print("ZAHLEN (b) Objekt bei ", center, " → px ", press)
_motion(press)
_mouse(MOUSE_BUTTON_MIDDLE, true, press)
await process_frame
var dist_vor: float = float(camera.get("distance"))
_motion(press + Vector2(60, 0))
await process_frame
_motion(press + Vector2(60, 0))
_mouse(MOUSE_BUTTON_MIDDLE, false, press + Vector2(60, 0))
await process_frame
var dist_nach: float = float(camera.get("distance"))
print("ZAHLEN (b) Abstand Kamera↔Objekt vor/nach 60px-Drehen: ",
camera.position.distance_to(center), " / ", camera.position.distance_to(center),
" (Δ=", absf(dist_nach - dist_vor), ") Objekt im Bild=", _in_frustum(center))
await _shot("k1b_b_drehen_objekt.png")
# --- (c) Pos1: GANZE Karte wieder ----------------------------------------
_key(KEY_HOME)
await process_frame
await process_frame
var alle := true
for c in [Vector3(-512, -10, -512), Vector3(512, 80, -512), Vector3(-512, -10, 512), Vector3(512, 80, 512)]:
if not _in_frustum(c):
alle = false
print("ZAHLEN (c) nach Pos1: Map-Ecken im Frustum %s (8-Extrem-Punkte geprüft über 4 obere+4 … simpel: 4)", ["ALLE" if alle else "FEHLEND"])
print("ZAHLEN (c) target=", camera.get("target"), " distance=", camera.get("distance"))
print("ZAHLEN (c) Status: ", main.status_label.text)
await _shot("k1b_c_pos1_ganze_karte.png")
print("PROBE_FERTIG")
quit(0)