diff --git a/core b/core index d196086..5e98535 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit d196086cce09fb729f6ff013e7e8216b56c5e977 +Subproject commit 5e98535a0afc83af4e4017806686a76af4913afd diff --git a/tests/test_terrain_stuecke.gd b/tests/test_terrain_stuecke.gd new file mode 100644 index 0000000..da18444 --- /dev/null +++ b/tests/test_terrain_stuecke.gd @@ -0,0 +1,93 @@ +extends SceneTree +## Editor-Test (headless): Terrain in Stücken zeigt dieselben Punkte wie das ganze +## Mesh, auch nach Pinselschritten mit Symmetrie. +## Ausführen: godot --headless --path . --script res://tests/test_terrain_stuecke.gd + +var failures := 0 +var checks := 0 + + +func _initialize() -> void: + _run.call_deferred() + + +func _check(cond: bool, label: String) -> void: + checks += 1 + if cond: + print(" ok: ", label) + else: + failures += 1 + print(" FAIL: ", label) + + +func _ansicht(stuecke: bool) -> TerrainMeshView: + TerrainMeshView.stuecke_an = stuecke + var v := TerrainMeshView.new() + root.add_child(v) + return v + + +## Alle Stück-Punkte müssen zum ganzen Mesh gehören, Stückgrenzen ohne Lücke. +func _gleich(ganz: TerrainMeshView, teile: TerrainMeshView, res: int) -> bool: + var a: Array = (ganz._mi.mesh as ArrayMesh).surface_get_arrays(0) + var pos: PackedVector3Array = a[Mesh.ARRAY_VERTEX] + var nor: PackedVector3Array = a[Mesh.ARRAY_NORMAL] # kommt komprimiert zurück + var gesehen := 0 + for s in teile._stuecke: + var arr: Array = s["arrays"] + var p: PackedVector3Array = arr[Mesh.ARRAY_VERTEX] + var n: PackedVector3Array = arr[Mesh.ARRAY_NORMAL] + var w: int = s["w"] + for i in p.size(): + var x: int = int(s["x0"]) + i % w + var z: int = int(s["z0"]) + i / w + var ziel := z * res + x + if p[i].distance_to(pos[ziel]) > 0.001 or n[i].distance_to(nor[ziel]) > 0.01: + print(" Abweichung bei ", x, ",", z) + return false + gesehen += 1 + return gesehen >= res * res + + +func _run() -> void: + var res := 129 + var size := 512.0 + var h := PackedFloat32Array() + h.resize(res * res) + for i in h.size(): + h[i] = 4.0 * sin(float(i) * 0.013) + var mats := PackedByteArray() + mats.resize(res * res) + + var ganz := _ansicht(false) + ganz.update_heights(h, res, size, size, mats) + var teile := _ansicht(true) + teile.update_heights(h, res, size, size, mats) + _check(teile._stuecke.size() == 16, "16 Stücke bei Raster 129") + _check(_gleich(ganz, teile, res), "Stücke zeigen dieselben Punkte wie das ganze Mesh") + _check(teile.triangle_count() == ganz.triangle_count(), "Gleiche Dreieckszahl") + + # Zwei getrennte Pinselflecken, einer davon über eine Stückgrenze. + var flecken := [Rect2i(28, 28, 10, 10), Rect2i(100, 90, 6, 6)] + for r: Rect2i in flecken: + for z in range(r.position.y, r.end.y): + for x in range(r.position.x, r.end.x): + h[z * res + x] += 3.0 + teile.markiere_hoehen(r) + TerrainMeshView.stuecke_an = false + ganz.update_heights(h) + TerrainMeshView.stuecke_an = true + teile.update_heights(h) + _check(_gleich(ganz, teile, res), "Nach Teil-Update wieder gleich, auch an Stückgrenzen") + + TerrainMeshView.stuecke_an = true + teile.update_heights(h, 0, 0.0, 0.0, PackedByteArray(), Rect2i(0, 0, 4, 4)) + _check(teile._dirty.is_empty(), "Mal-Schritt fasst die Punkte nicht an") + + TerrainMeshView.stuecke_an = false + if failures == 0: + print("ALL OK: %d checks" % checks) + quit(0) + else: + print("FAILED: %d/%d checks" % [failures, checks]) + quit(1) diff --git a/tests/test_terrain_stuecke.gd.uid b/tests/test_terrain_stuecke.gd.uid new file mode 100644 index 0000000..520dac7 --- /dev/null +++ b/tests/test_terrain_stuecke.gd.uid @@ -0,0 +1 @@ +uid://bnmlkmeh1g002 diff --git a/tools/sync_loadout_katalog.py b/tools/sync_loadout_katalog.py index 93aee70..cf4ed9c 100644 --- a/tools/sync_loadout_katalog.py +++ b/tools/sync_loadout_katalog.py @@ -26,7 +26,7 @@ for wid in sorted(profile): } waffen[wid] = eintrag -ziel = os.path.join(hier, "..", "library", "loadout_katalog.json") +ziel = os.path.join(hier, "..", "core", "library", "loadout_katalog.json") with open(ziel, "w", encoding="utf-8") as f: json.dump({"version": 1, "waffen": waffen}, f, ensure_ascii=False, indent=1, sort_keys=True) print("%d Waffen -> %s" % (len(waffen), os.path.normpath(ziel)))