scopedvr-map-editor/tests/probe_d1_walls_render.gd

91 lines
3.3 KiB
GDScript

extends SceneTree
## D1-Render-Probe im MAP BUILDER (t_78746c97): 4 Wand-Objekte werden als
## Map-Dokument platziert und der Editor-Viewport gerendert — Sichtprüfung
## „stehen die Wände AUF dem Boden (Gitterebene y=0)?“.
##
## xvfb-run -a /opt/data/home/bin/godot4 --path . --rendering-driver opengl3 \
## -s res://tests/probe_d1_walls_render.gd
##
## Ausgabe: PROBE_D1_EDITOR_OK / _FAIL + PNG im Scratch-Ordner.
const OUT_PNG := "/opt/data/profiles/scopedvr-dev/cache/scratch/d1_editor_waende.png"
const PLATZ := [
{"id": "wall_001", "pos": [-8.0, 0.0, 0.0], "rot_y_deg": 0.0},
{"id": "wall_010", "pos": [-3.0, 0.0, 0.0], "rot_y_deg": 25.0},
{"id": "wall_074", "pos": [3.0, 0.0, 0.0], "rot_y_deg": -25.0},
{"id": "wall_100", "pos": [8.0, 0.0, 0.0], "rot_y_deg": 90.0},
]
var fehler: Array = []
func _initialize() -> void:
_run()
func _run() -> void:
await process_frame
await process_frame
var manifest: Dictionary = JSON.parse_string(
FileAccess.get_file_as_string(SvmapIO.MANIFEST_PATH))
var lib: Dictionary = manifest.get("objects", {})
var walls := 0
for oid in lib.keys():
if str((lib[oid] as Dictionary).get("kategorie", "")) == "walls":
walls += 1
print("Editor-Registry: %d Objekte, davon 'walls': %d" % [lib.size(), walls])
if walls != 50:
fehler.append("Editor-Bibliothek hat %d Wände statt 50" % walls)
var builder := Node3D.new()
builder.set_script(load("res://src/viewport/map_view_builder.gd"))
root.add_child(builder)
var doc: Dictionary = SvmapDocument.create_new("D1 Waende", 64.0, "mittag")
doc["objects"] = PLATZ
builder.call("rebuild", doc, manifest)
builder.call("set_grid_visible", true)
await process_frame
var fehlend: Array = builder.get("fehlende_glbs")
print("fehlende_glbs (OIDs ohne echtes GLB): %s" % str(fehlend))
for oid in ["wall_001", "wall_010", "wall_074", "wall_100"]:
if fehlend.has(oid):
fehler.append("%s landet im Editor auf dem Platzhalter" % oid)
var markers: Array = builder.get("object_markers")
print("platzierte Objekt-Marker: %d" % markers.size())
if markers.size() != 4:
fehler.append("erwartet 4 Marker, sind %d" % markers.size())
for i in markers.size():
var m: Node3D = markers[i]
if m == null:
fehler.append("Marker %d ist null" % i)
continue
var mi := m.get_child(0) as MeshInstance3D
var aabb := mi.mesh.get_aabb()
var unten := mi.global_position.y + aabb.position.y * mi.scale.y
print(" %-10s meta_glb=%s unterkante=%.3f hoehe=%.2f dreiecke=%d" % [
str(m.get_meta("oid", "?")), str(bool(m.get_meta("glb", false))),
unten, aabb.size.y * mi.scale.y, mi.mesh.get_faces().size() / 3])
if not bool(m.get_meta("glb", false)):
fehler.append("Marker %d: meta glb = false (Platzhalter)" % i)
if absf(unten) > 0.05:
fehler.append("Marker %d: Unterkante %.3f m statt 0 (schwebt/versunken)" % [i, unten])
# --- Render ---
var cam := Camera3D.new()
builder.add_child(cam)
cam.position = Vector3(0.0, 7.0, 17.0)
cam.look_at(Vector3(0.0, 2.5, 0.0))
cam.current = true
await process_frame
await process_frame
await RenderingServer.frame_post_draw
var img := root.get_texture().get_image()
img.save_png(OUT_PNG)
print("PROBE_SAVED %s (%dx%d)" % [OUT_PNG, img.get_width(), img.get_height()])
for f in fehler:
print(" FEHLER: %s" % f)
print("PROBE_D1_EDITOR_%s" % ("FAIL" if not fehler.is_empty() else "OK"))
quit(0 if fehler.is_empty() else 1)