extends SceneTree ## WEGWERF-Renderprobe (Karte t_96e3c4ee, Test-Startpunkt per Klick) — ## (a) Editor mit sichtbarem Marker am gesetzten Test-Start ## (b) F5 startet den Testlauf GENAU dort (HUD + Startposition) ## (c) T im Testlauf versetzt zum Blickpunkt (+ setzt den Test-Start neu) ## Ausführen: ## xvfb-run -a godot4 --path . --rendering-driver opengl3 -s res://tests/probe_t1b_render.gd ## Wegwerf-Probe (nicht im Repo-Commit), Beweise nach /opt/data/scopedvr/work/t96e3_beweise/. var main: Control var subvp: SubViewport func _initialize() -> void: _run.call_deferred() func _shot(name: String) -> void: await process_frame await process_frame await RenderingServer.frame_post_draw # ROOT-Viewport = das ganze Fenster (Editor-UI + 3D-Ansicht + HUD) — # exakt das, was Sly auf dem Desktop sieht. var img := root.get_texture().get_image() img.save_png(_png(name)) print("PROBE_PNG=%s (%dx%d)" % [_png(name), img.get_width(), img.get_height()]) func _png(name: String) -> String: return "/opt/data/scopedvr/work/t96e3_beweise/" + name 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 _press_key(code: Key) -> InputEventKey: var key := InputEventKey.new() key.keycode = code key.physical_keycode = code key.pressed = true return key func _run() -> void: DirAccess.make_dir_recursive_absolute("/opt/data/scopedvr/work/t96e3_beweise") var scene: PackedScene = load("res://scenes/main.tscn") main = scene.instantiate() root.add_child(main) await process_frame await process_frame subvp = _find_subvp(main) var container: SubViewportContainer = subvp.get_parent() container.stretch = false subvp.size = Vector2i(1600, 900) await process_frame # Test-Map: hügeliges Ramp-Terrain, V11-konforme Spawns, Objekte zum Ansehen. var doc: Dictionary = SvmapDocument.create_new("T1b-Probe", 100.0, "mittag") var terrain: Dictionary = doc.get("terrain", {}) var res := int(terrain.get("resolution", 0)) var heights := PackedFloat32Array() heights.resize(res * res) for zi in res: for xi in res: heights[zi * res + xi] = 2.0 + float(xi) * 0.06 terrain["min_height_m"] = 2.0 terrain["max_height_m"] = 2.0 + float(res - 1) * 0.06 terrain["heightmap_r16_b64"] = TerrainField.encode(heights, 2.0, 2.0 + float(res - 1) * 0.06) doc["objects"] = [ {"id": "crate_wood", "pos": [26.0, 0.0, -30.0], "scale": 1.0, "rot_y_deg": 0.0}, {"id": "crate_wood", "pos": [14.0, 0.0, -24.0], "scale": 1.0, "rot_y_deg": 30.0}, {"id": "watchtower_wood", "pos": [-30.0, 0.0, 20.0], "scale": 1.0, "rot_y_deg": 0.0}, ] doc["spawn_zones"] = { "0": {"points": [ {"id": "A1", "pos": [-20.0, 0.0, 0.0]}, {"id": "A2", "pos": [-24.0, 0.0, 2.0]}, {"id": "A3", "pos": [-22.0, 0.0, -3.0]}, {"id": "A4", "pos": [-26.0, 0.0, -2.0]}, ]}, "1": {"points": [ {"id": "B1", "pos": [20.0, 0.0, 0.0]}, {"id": "B2", "pos": [24.0, 0.0, 2.0]}, {"id": "B3", "pos": [22.0, 0.0, -3.0]}, {"id": "B4", "pos": [26.0, 0.0, -2.0]}, ]}, } main.set("doc", doc) main.set("current_path", "") main.set("dirty", false) main.get("history").begin(doc) main.call("_clear_edit_state") main.call("_refresh_all") await process_frame await process_frame # --- (a) Test-Start setzen (Demo-Klick) + Editor-Ansicht auf den Marker --- var tool: Node = main.get("test_start_tool") tool.call("demo_set", 20.0, -30.0) var marker: Node3D = tool.get("_marker") var h: float = SvmapDocument.terrain_height_at(doc, 20.0, -30.0) print("ZAHLEN (a) Marker: pos=", marker.position, " sichtbar=", marker.visible, " | Terrainhöhe dort=", h) print("ZAHLEN (a) Status: ", main.status_label.text) main.call("_demo_camera", Vector3(20.0, h, -30.0) + Vector3(9.0, 7.0, 9.0), 16.0, 30.0, -45.0) await _shot("t1b_a_editor_marker.png") # --- (b) F5: Testlauf startet GENAU am Test-Start -------------------------- main.call("_on_test_run") await process_frame await process_frame var pt: Node = main.get("playtest") var body: Node3D = pt.get("body") print("ZAHLEN (b) Start: body.position=", body.position, " | erwartet x=20 z=-30 Höhe=", body.call("terrain_height", 20.0, -30.0)) print("ZAHLEN (b) Marker sichtbar im Spiel=", marker.visible) print("ZAHLEN (b) Status: ", main.status_label.text) await _shot("t1b_b_test_start_dort.png") # --- (c) T im Testlauf: Blick anheben → Teleport zum Blickpunkt ------------ body.set("yaw_deg", 20.0) body.set("pitch_deg", -25.0) body.call("_apply_look") var eye: Vector3 = body.position + Vector3(0.0, 1.7, 0.0) var cam: Camera3D = body.get("look_cam") var dir: Vector3 = cam.global_transform.basis * Vector3(0.0, 0.0, -1.0) print("ZAHLEN (c) vor T: pos=", body.position, " blick_dir=", dir) main._unhandled_key_input(_press_key(KEY_T)) await process_frame await process_frame print("ZAHLEN (c) nach T: pos=", body.position, " | main.test_start_point=", main.get("test_start_point")) print("ZAHLEN (c) HUD: ", (pt.get("hud_msg") as Label).text) await _shot("t1b_c_teleport.png") # --- (d) ESC: zurück, Marker zeigt auf die neue Stelle --------------------- main._unhandled_key_input(_press_key(KEY_ESCAPE)) await process_frame await process_frame print("ZAHLEN (d) playtest=null: ", main.get("playtest") == null, " | Marker pos=", marker.position, " sichtbar=", marker.visible) await _shot("t1b_d_editor_marker_neu.png") print("PROBE_FERTIG") quit(0)