extends SceneTree
## Gate: selection is OUTLINED, not washed (docs/editor-texturing-selection-move.md §3).
##
## User 2026-10-03: "I can't actually see what I am working on." Brush selection filled
## every face cyan at 0.35, double-sided, through walls. Now: no fill for brushes; the
## active brush #ffa028 3 px, other selected #ed5700 2 px, each with a faint hidden copy;
## a selected face gets a #ffb700 3 px outline and a light DEPTH-TESTED tint; the
## always-on wireframe is neutral grey.
##
## Run: HYPERTPS_DAEMON_TCP=127.0.0.1:1 "$HYPER_TPS_GODOT" --headless --path . --script res://scenes/test/gate_selection_outline.gd
var ok := true
var checks := 0
var _frame := 0
var _map: Node
func _p(c: bool, m: String, got: Variant = "") -> void:
checks += 1
print(("ok " if c else "FAIL: ") + m + ("" if str(got) == "" else " (" + str(got) + ")"))
if not c:
ok = false
func _process(_d: float) -> bool:
_frame += 1
if _frame == 1:
_map = (load("res://scenes/maps/map_flat.tscn") as PackedScene).instantiate()
root.add_child(_map)
return false
if _frame < 30:
return false
_run()
if checks < 12:
_p(false, "only %d checks ran" % checks)
print("GATE selection_outline: %s (%d checks)" % ["PASS" if ok else "FAIL", checks])
quit(0 if ok else 1)
return true
func _box(lo: Vector3, hi: Vector3) -> PackedFloat32Array:
return PackedFloat32Array([1, 0, 0, hi.x, -1, 0, 0, -lo.x, 0, 1, 0, hi.y, 0, -1, 0, -lo.y, 0, 0, 1, hi.z, 0, 0, -1, -lo.z])
static func _near(c: Variant, want: Color) -> bool:
return c is Color and absf((c as Color).r - want.r) < 0.02 and absf((c as Color).g - want.g) < 0.02 \
and absf((c as Color).b - want.b) < 0.02
func _run() -> void:
var level: Node = _map.get_node("DCLevel")
var a: int = level.add_brush(_box(Vector3(0, 0, 0), Vector3(1, 1, 1)), 1, PackedInt32Array(), 0, false, "sel-a")
var b: int = level.add_brush(_box(Vector3(3, 0, 0), Vector3(4, 1, 1)), 1, PackedInt32Array(), 0, false, "sel-b")
level.rebuild()
print("-- brush selection (click path: every face key, kind brush) --")
_map.select_brushes(PackedInt32Array([a, b])) # b is active (last)
_map.set("_sel_keys", level.get_brush(b).get("plane_keys", PackedStringArray()))
_map.set("_sel_kind", "brush")
_map._update_face_highlight()
_map._update_element_highlight()
var hl: MeshInstance3D = _map.get("_hl")
_p(hl == null or hl.mesh == null or hl.mesh.get_surface_count() == 0, "NO face wash for a brush selection")
_p(_map.has_method("_ensure_outline"), "the map owns a SelectionOutline")
if not _map.has_method("_ensure_outline"):
return
var ol: Node = _map._ensure_outline()
var act: Dictionary = ol.layer_info("active")
var sel: Dictionary = ol.layer_info("selected")
_p(int(act.get("segments", 0)) == 12, "active brush: 12 edges outlined", act.get("segments"))
_p(_near(act.get("color"), Color("#ffa028")) and is_equal_approx(float(act.get("width", 0)), 3.0),
"active: #ffa028, 3 px", act)
_p(int(sel.get("segments", 0)) == 12, "other selected brush: 12 edges", sel.get("segments"))
_p(_near(sel.get("color"), Color("#ed5700")) and is_equal_approx(float(sel.get("width", 0)), 2.0),
"selected: #ed5700, 2 px", sel)
_p(float(act.get("hidden_alpha", 0)) > 0.2 and float(act.get("hidden_alpha", 0)) < 0.5,
"a faint copy for hidden edges", act.get("hidden_alpha"))
print("-- face selection --")
var keys: PackedStringArray = level.get_brush(b).get("plane_keys", PackedStringArray())
_map.set("_sel_brushes", [b] as Array[int])
_map.set("_sel_brush", b)
_map.set("_sel_kind", "face")
_map.set("_sel_keys", PackedStringArray([keys[2]]))
_map._update_face_highlight()
_map._update_element_highlight()
hl = _map.get("_hl")
_p(hl != null and hl.mesh != null and hl.mesh.get_surface_count() == 1, "the face gets a tint")
var m: StandardMaterial3D = hl.material_override if hl != null else null
_p(m != null and not m.no_depth_test, "tint is DEPTH-TESTED (not drawn through walls)")
_p(m != null and m.albedo_color.a <= 0.15, "tint is light (<= 15 %)", m.albedo_color if m != null else "")
var fc: Dictionary = ol.layer_info("face")
_p(int(fc.get("segments", 0)) == 4 and _near(fc.get("color"), Color("#ffb700")) and is_equal_approx(float(fc.get("width", 0)), 3.0),
"face outline: 4 edges, #ffb700, 3 px", fc)
_p(int(ol.layer_info("active").get("segments", 0)) == 0 and int(ol.layer_info("selected").get("segments", 0)) == 0,
"brush outlines cleared in face mode")
print("-- wireframe --")
var c: Color = BrushView.COLOR_ALL
_p(absf(c.r - c.g) < 0.05 and absf(c.g - c.b) < 0.05, "always-on wireframe is neutral grey", c)