scopedvr-map-editor/tests/probe_d3_buildings_render.gd

124 lines
4.7 KiB
GDScript

extends SceneTree
## D3 (t_6690c59c) Map-Builder-Beweis: 3 Gebaeude (Hangar, Kaserne, Container)
## mit dem ECHTEN Editor-Viewport-Bauer (MapViewBuilder.rebuild) platzieren,
## Fusspunkt/Groesse messen und ein PNG fuer die Sichtpruefung rendern.
##
## Aufruf (braucht Rendering — NICHT --headless):
## PROBE_OUT_DIR=/tmp xvfb-run -a godot --path . --rendering-driver opengl3 \
## -s res://tests/probe_d3_buildings_render.gd
## Ausgabe: d3_buildings_mapbuilder.png + PROBE_*-Zeilen
const OBJEKTE := [
{"id": "hangar_001", "pos": [-48.0, 0.0, 0.0], "rot_y_deg": 0.0, "scale": 1.0},
{"id": "barracks_001", "pos": [0.0, 0.0, 0.0], "rot_y_deg": 90.0, "scale": 1.0},
{"id": "container_001", "pos": [38.0, 0.0, 4.0], "rot_y_deg": 30.0, "scale": 1.0},
]
var failures := 0
var checks := 0
var builder: Node3D
func _initialize() -> void:
_run()
func _check(cond: bool, label: String) -> void:
checks += 1
if cond:
print(" ok: %s" % label)
else:
failures += 1
print(" FAIL: %s" % label)
func _run() -> void:
await process_frame
await process_frame
var manifest: Dictionary = JSON.parse_string(
FileAccess.get_file_as_string(SvmapIO.MANIFEST_PATH))
if not (manifest is Dictionary):
printerr("FAIL: Registry nicht lesbar")
quit(1)
return
var lib: Dictionary = manifest.get("objects", {})
# --- Map-Dokument wie im Editor (SvmapDocument.create_new), flaches Terrain ---
var doc: Dictionary = SvmapDocument.create_new("D3 Gebaeude-Probe", 256.0, "mittag")
doc["objects"] = OBJEKTE
builder = Node3D.new()
builder.set_script(load("res://src/viewport/map_view_builder.gd"))
root.add_child(builder)
builder.call("rebuild", doc, manifest)
await process_frame
await process_frame
print("PROBE_REGISTRY %d Objekte" % lib.size())
for obj in OBJEKTE:
var oid: String = obj["id"]
var eintrag: Dictionary = lib.get(oid, {})
_check(not eintrag.is_empty(), "%s in der Bibliothek" % oid)
# --- Platzierung: echter GLB-Marker, Fusspunkt auf y=0, XZ zentriert ---
var marker: Array = builder.get("object_markers")
_check(marker.size() == 3, "3 Objekt-Marker im Viewport (ist: %d)" % marker.size())
_check((builder.get("fehlende_glbs") as Array).is_empty(),
"keine fehlenden GLBs (Platzhalter): %s" % str(builder.get("fehlende_glbs")))
var ter = builder.get("terrain_view")
for i in OBJEKTE.size():
var oid: String = OBJEKTE[i]["id"]
var m: Node3D = marker[i]
var mi: MeshInstance3D = null
for k in m.get_children():
if k is MeshInstance3D:
mi = k
var mesh: Mesh = mi.mesh
var aabb: AABB = mesh.get_aabb()
var pos: Vector3 = m.position
var boden: float = SvmapDocument.terrain_height_at(doc, pos.x, pos.z)
print("PROBE_OBJ %s: marker=(%.2f, %.2f, %.2f) terrainhöhe=%.3f aabb_size=(%.3f, %.3f, %.3f) aabb_min.y=%.4f xz_zentrum=(%.4f, %.4f)"
% [oid, pos.x, pos.y, pos.z, boden, aabb.size.x, aabb.size.y, aabb.size.z,
aabb.position.y, aabb.get_center().x, aabb.get_center().z])
_check(bool(m.get_meta("glb", false)), "%s: echtes GLB-Mesh (meta glb)" % oid)
_check(absf(pos.y - boden) < 0.01, "%s: Marker sitzt auf der Terrainhoehe (%.3f)" % [oid, boden])
_check(absf(aabb.position.y) < 0.02, "%s: Mesh-Unterkante y=0 (%.4f)" % [oid, aabb.position.y])
_check(absf(aabb.get_center().x) < 0.02 and absf(aabb.get_center().z) < 0.02,
"%s: XZ zentriert" % oid)
# Groessenverhaeltnis (Sichtpruefung „richtige Groesse relativ zueinander")
var h_aabb: AABB = ((marker[0] as Node3D).get_child(0) as MeshInstance3D).mesh.get_aabb()
var c_aabb: AABB = ((marker[2] as Node3D).get_child(0) as MeshInstance3D).mesh.get_aabb()
print("PROBE_GROESSE Hangar=%.1f x %.1f x %.1f m | Container=%.1f x %.1f x %.1f m (Faktor %.1fx)"
% [h_aabb.size.x, h_aabb.size.y, h_aabb.size.z,
c_aabb.size.x, c_aabb.size.y, c_aabb.size.z,
h_aabb.size.x / maxf(0.01, c_aabb.size.x)])
_check(h_aabb.size.y > 4.0 * c_aabb.size.y, "Hangar deutlich groesser als der Container")
# --- Rendern (Luftbild ueber die drei Gebaeude) ---
var cam := Camera3D.new()
root.add_child(cam)
cam.fov = 55.0
cam.position = Vector3(-8.0, 32.0, 88.0)
cam.look_at(Vector3(-6.0, 5.0, 0.0), Vector3.UP)
cam.current = true
await process_frame
await process_frame
await RenderingServer.frame_post_draw
var img: Image = root.get_texture().get_image()
var out_dir := OS.get_environment("PROBE_OUT_DIR")
if out_dir.is_empty():
out_dir = "/tmp"
var pfad := out_dir + "/d3_buildings_mapbuilder.png"
img.save_png(pfad)
print("PROBE_IMG %s size=%s" % [pfad, str(img.get_size())])
if ter != null:
print("PROBE_TERRAIN sichtbar=%s" % str((ter as Node3D).visible))
if failures == 0:
print("PROBE_D3_MAPBUILDER OK (%d checks)" % checks)
quit(0)
else:
print("PROBE_D3_MAPBUILDER FAILED (%d/%d)" % [failures, checks])
quit(1)