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

126 lines
4.8 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
## RENDER-PROBE Karte t_6c1027c1 (K1d: Startansicht = Kartenmitte, 80 m) — 2 Bilder 1600×900:
## (a) Karte „frisch geladen“ (main._refresh_all → fit_to_document): Blick aus
## 80 m auf die Kartenmitte, Lager im Nahbereich groß im Bild
## (b) Pos1 (Home) → GANZE Karte im Bild (Startansicht ist bewusst NICHT Pos1)
## Ausführen (KEIN --headless, sonst rendert nichts):
## xvfb-run -a /opt/data/home/bin/godot4 --path . --rendering-driver opengl3 -s res://tests/probe_k1d_render.gd
## PNGs landen in /opt/data/scopedvr/work/k1d_bilder/ (Scratch-Ordner stirbt nach der Karte).
## Echte GLB-Modelle: die Probe braucht ein Mesh-Lager als Sibling
## (../scopedvr-client/assets/objekte) — ohne das zeigen die Marker Platzhalter.
const OUT_DIR := "/opt/data/scopedvr/work/k1d_bilder/"
var main: Control
var camera: Camera3D
var subvp: SubViewport
func _initialize() -> void:
_run.call_deferred()
func _shot(name: String) -> void:
await process_frame
await RenderingServer.frame_post_draw
var img := subvp.get_texture().get_image()
var path := OUT_DIR + name
var err := img.save_png(path)
print("PROBE_PNG=%s (%dx%d, err=%d)" % [path, img.get_width(), img.get_height(), err])
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 _key(code: Key) -> void:
var ev := InputEventKey.new()
ev.keycode = code
ev.physical_keycode = code
ev.pressed = true
subvp.push_input(ev)
## Lager um die Kartenmitte: Gebäude/Container/Fässer im Nahbereich (das soll
## die 80-m-Ansicht „groß und greifbar“ zeigen) + ein paar Objekte weiter
## draußen für den Karten-Kontext.
func _lager_doc() -> Dictionary:
var doc: Dictionary = SvmapDocument.create_new("K1d-Beweis", 1024.0, "mittag")
doc["objects"] = [
{"id": "barracks_001", "pos": [-16.0, 0.0, -8.0], "scale": 1.0, "rot_y_deg": 20.0},
{"id": "building_001", "pos": [14.0, 0.0, -14.0], "scale": 1.0, "rot_y_deg": -35.0},
{"id": "container_001", "pos": [3.0, 0.0, 7.0], "scale": 1.0, "rot_y_deg": 90.0},
{"id": "container_004", "pos": [7.5, 0.0, 7.0], "scale": 1.0, "rot_y_deg": 90.0},
{"id": "barrel_001", "pos": [-4.0, 0.0, -2.0], "scale": 1.0, "rot_y_deg": 0.0},
{"id": "barrel_003", "pos": [-3.0, 0.0, -4.0], "scale": 1.0, "rot_y_deg": 0.0},
{"id": "barrel_005", "pos": [-4.6, 0.0, -4.6], "scale": 1.0, "rot_y_deg": 0.0},
{"id": "barrier_001", "pos": [10.0, 0.0, 22.0], "scale": 1.0, "rot_y_deg": 0.0},
{"id": "apc_001", "pos": [22.0, 0.0, 6.0], "scale": 1.0, "rot_y_deg": 140.0},
{"id": "air_defense_001", "pos": [-24.0, 0.0, 16.0], "scale": 1.0, "rot_y_deg": 70.0},
{"id": "container_007", "pos": [-80.0, 0.0, -90.0], "scale": 1.0, "rot_y_deg": 15.0},
{"id": "barracks_001", "pos": [130.0, 0.0, 90.0], "scale": 1.0, "rot_y_deg": -60.0},
]
return doc
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
var doc := _lager_doc()
main.set("doc", doc)
main.call("_refresh_all")
await process_frame
await process_frame
var target: Vector3 = camera.get("target")
print("ZAHLEN (a) target=", target, " distance=", camera.get("distance"),
" yaw=", camera.get("yaw_deg"), " pitch=", camera.get("pitch_deg"))
print("ZAHLEN (a) Kamera-Position=", camera.position,
" Höhe über Kartenmitte=", camera.position.y - target.y)
print("ZAHLEN (a) Status: ", main.status_label.text)
# Wie viele Objekt-Marker liegen wirklich im Bild?
var builder = main.get("view_builder")
var markers: Array = builder.get("object_markers")
var drin := 0
var rect: Rect2 = Rect2(Vector2.ZERO, Vector2(subvp.size))
for m in markers:
if not (m is Node3D) or not is_instance_valid(m):
continue # unbekannte Objekt-ID → kein Marker (Platzhalter-Zweig)
var mp: Vector3 = (m as Node3D).global_position
var p := camera.unproject_position(mp)
if rect.has_point(p) and camera.is_position_in_frustum(mp):
drin += 1
print("ZAHLEN (a) Objekt-Marker im Bild: %d / %d" % [drin, markers.size()])
await _shot("k1d_a_startansicht_80m.png")
_key(KEY_HOME)
await process_frame
await process_frame
print("ZAHLEN (b) nach Pos1: target=", camera.get("target"),
" distance=", camera.get("distance"), " Status: ", main.status_label.text)
var ecken := 0
for x in [-512.0, 512.0]:
for y in [-10.0, 80.0]:
for z in [-512.0, 512.0]:
if camera.is_position_in_frustum(Vector3(x, y, z)):
ecken += 1
print("ZAHLEN (b) Map-Ecken im Frustum: %d/8" % ecken)
await _shot("k1d_b_pos1_ganze_karte.png")
print("PROBE_FERTIG")
quit(0)