126 lines
4.8 KiB
GDScript
126 lines
4.8 KiB
GDScript
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)
|