extends SceneTree
## REPRO: does a clearance volume placed OUTSIDE the level actually reach the
## terrain subtract, in the REAL map_dc_world?
##
## Not a gate yet — a diagnosis. Each stage prints, so the first one that is
## wrong is the answer instead of "it does not work".
const MAP_SCENE := "res://scenes/maps/map_dc_world.tscn"
var _map: Node = null
var _t0 := 0
var _done := false
static func _box(lo: Vector3, hi: Vector3) -> PackedFloat32Array:
return PackedFloat32Array([
-1, 0, 0, -lo.x, 1, 0, 0, hi.x,
0, -1, 0, -lo.y, 0, 1, 0, hi.y,
0, 0, -1, -lo.z, 0, 0, 1, hi.z,
])
func _initialize() -> void:
_t0 = Time.get_ticks_msec()
_map = (load(MAP_SCENE) as PackedScene).instantiate()
root.add_child(_map)
func _process(_d: float) -> bool:
if _done:
return true
var lvl: Node = _map.get("level")
if lvl == null or not is_instance_valid(lvl) or lvl.get_brush_count() == 0:
if Time.get_ticks_msec() - _t0 > 90000:
print("FAIL — level never imported"); quit(1); return true
return false
_done = true
print("\n=== 1. baseline ===")
var s0: Dictionary = lvl.build_shell()
print(" brushes=%d shell tris=%d vol=%.0f sealed=%s"
% [lvl.get_brush_count(), int(s0.get("triangles", 0)),
float(s0.get("volume", 0.0)), str(s0.get("sealed", false))])
# A bore well outside the level, in open void — the hillside case.
var mi := lvl.get_node_or_null("LevelMesh") as MeshInstance3D
var ab: AABB = mi.get_aabb() if mi != null else AABB()
print(" level aabb: %s size %s" % [str(ab.position), str(ab.size)])
var out_lo := Vector3(ab.position.x + ab.size.x + 2.0, ab.position.y + 2.0,
ab.position.z + ab.size.z * 0.5)
var out_hi := out_lo + Vector3(8.0, 2.5, 1.5)
var mid := (out_lo + out_hi) * 0.5
print("\n=== 2. add the clearance brush ===")
var id: int = lvl.add_brush(_box(out_lo, out_hi), 0, PackedInt32Array(), 0,
false, "repro:1", true)
print(" add_brush -> id %d (0 means the store REFUSED it)" % id)
print(" clearance ids: %s" % str(lvl.get_clearance_brush_ids()))
lvl.rebuild()
print("\n=== 3. does the SHELL enclose the bore? ===")
var s1: Dictionary = lvl.build_shell()
print(" shell tris=%d vol=%.0f sealed=%s interior=%.0f solid=%.0f"
% [int(s1.get("triangles", 0)), float(s1.get("volume", 0.0)),
str(s1.get("sealed", false)), float(s1.get("interior_volume", 0.0)),
float(s1.get("solid_volume", 0.0))])
print(" triangles grew: %s" % str(int(s1.get("triangles", 0)) > int(s0.get("triangles", 0))))
var verts: PackedVector3Array = s1.get("vertices", PackedVector3Array())
var idx: PackedInt32Array = s1.get("indices", PackedInt32Array())
var f := FileAccess.open("/tmp/repro_shell.obj", FileAccess.WRITE)
for v: Vector3 in verts:
f.store_line("v %.6f %.6f %.6f" % [v.x, v.y, v.z])
for i in range(0, idx.size(), 3):
f.store_line("f %d %d %d" % [idx[i] + 1, idx[i+1] + 1, idx[i+2] + 1])
f.close()
print(" wrote /tmp/repro_shell.obj (%d verts) — bore centre %s"
% [verts.size(), str(mid)])
print("\n=== 4. the cache key, which decides whether a reshell even runs ===")
print(" key now: %s" % _map._shell_cache_key())
print(" key stamped: %s" % _map._shell_key_stamped)
print(" differ (so a fold WOULD re-derive): %s"
% str(_map._shell_cache_key() != _map._shell_key_stamped))
print("\n=== 5. terrain present? ===")
print(" terrain: %s (headless frees it — a null here is EXPECTED and means "
% str(_map.terrain) + "the stamp cannot be observed in this harness)")
quit(0)
return true