OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-tps commits / b8697c9

#120 L2 step 2: through-depth (§13.3)
CutDepth.through(pieces, origin, normal, margin): the farthest any target piece reaches below the drawn plane, plus the margin (one grid step); 0 when the targets lie wholly on the plane's outer side. Measured once at commit. gate_cut_through (6). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
b8697c960eea6b474962f2c83915494c51a2d7e5
by plankatron <fleeky@gmail.com> · 2026-10-19T00:34:19.000Z

Changed files (2) +71 -0

scenes/maps/cut_depth.gd +22 -0
……@@ -0,0 +1,22 @@
1extends RefCounted
2## THROUGH-DEPTH (#120 L2 §13.3; BoxCutter's lazorcut): how deep a cutter drawn on a plane
3## must go to pass right through its targets.
4##
5## The farthest any target piece reaches below the plane (its corners projected on −n),
6## plus `margin` (the tool passes one grid step), so the far face is cut cleanly rather
7## than left as a skin. The maximum over the WHOLE target is safe: extra depth only cuts
8## where the cutter overlaps the target, so a deep part elsewhere costs nothing.
9##
10## Measured ONCE, at commit, and stored as a number (not re-measured in the fold, which
11## would make it depend on the targets' state in a new way).
12
13
14## `pieces` = plane sets (PackedFloat32Array, n·x <= d); `origin` / `normal` = the drawn
15## plane, its normal pointing OUT of the targets. 0 when nothing lies below the plane.
16static func through(pieces: Array, origin: Vector3, normal: Vector3, margin: float) -> float:
17 var down := -normal.normalized()
18 var deepest := 0.0
19 for pl: Variant in pieces:
20 for c: Vector3 in FaceKit.corners(pl as PackedFloat32Array):
21 deepest = maxf(deepest, down.dot(c - origin))
22 return deepest + margin if deepest > 1.0e-4 else 0.0
scenes/test/gate_cut_through.gd +49 -0
……@@ -0,0 +1,49 @@
1extends SceneTree
2## GATE — THROUGH-DEPTH (#120 L2 §13.3, cut_depth.gd).
3## T1 a slab y 0..2, drawn on its top (y 2, normal +y): depth 2 + the margin
4## T2 a stepped target (a second piece down to y -1): it reaches the deepest piece
5## T3 two targets: the deeper one decides
6## T4 drawn on a side face (normal +x): depth = the slab's width + margin
7## T5 the target wholly on the outer side: 0 (the tool then keeps its set depth)
8## T6 a plane floating above the target: down to its bottom
9##
10## RUN: CI=true HYPERTPS_DAEMON_TCP=127.0.0.1:1 "$GODOT" --headless --path . --script res://scenes/test/gate_cut_through.gd
11
12const CutDepth := preload("res://scenes/maps/cut_depth.gd")
13
14var fails := 0
15var checks := 0
16
17
18func _p(c: bool, m: String, got: Variant = "") -> void:
19 checks += 1
20 if not c:
21 fails += 1
22 print(" %-62s %s %s" % [m, "OK" if c else "**FAIL**", str(got)])
23
24
25func _box(a: Vector3, b: Vector3) -> PackedFloat32Array:
26 return PackedFloat32Array([-1, 0, 0, -a.x, 1, 0, 0, b.x, 0, -1, 0, -a.y, 0, 1, 0, b.y, 0, 0, -1, -a.z, 0, 0, 1, b.z])
27
28
29func _initialize() -> void:
30 var slab := _box(Vector3(0, 0, 0), Vector3(4, 2, 4))
31 var up := Vector3.UP
32 var d1 := CutDepth.through([slab], Vector3(2, 2, 2), up, 0.25)
33 _p(is_equal_approx(d1, 2.25), "T1 a slab drawn on its top: 2 + 0.25", d1)
34 var step := _box(Vector3(0, -1, 0), Vector3(1, 0, 1))
35 var d2 := CutDepth.through([slab, step], Vector3(2, 2, 2), up, 0.25)
36 _p(is_equal_approx(d2, 3.25), "T2 a stepped target: down to its deepest piece", d2)
37 var deep := _box(Vector3(10, -3, 0), Vector3(12, 2, 2))
38 var d3 := CutDepth.through([slab, deep], Vector3(2, 2, 2), up, 0.25)
39 _p(is_equal_approx(d3, 5.25), "T3 two targets: the deeper one decides", d3)
40 var d4 := CutDepth.through([slab], Vector3(4, 1, 2), Vector3.RIGHT, 0.25)
41 _p(is_equal_approx(d4, 4.25), "T4 drawn on the side face: the width + 0.25", d4)
42 # The target wholly on the plane's OUTER side (the normal points at it): nothing to cut.
43 var d5 := CutDepth.through([slab], Vector3(2, -5, 2), up, 0.25)
44 _p(d5 == 0.0, "T5 the target wholly above the plane: 0", d5)
45 # A plane floating above the slab still has all of it below: through reaches its bottom.
46 var d6 := CutDepth.through([slab], Vector3(2, 5, 2), up, 0.25)
47 _p(is_equal_approx(d6, 5.25), "T6 a plane above the slab: down to its bottom", d6)
48 print("\nGATE cut_through: %s (%d checks, %d failed)" % ["PASS" if fails == 0 else "FAIL", checks, fails])
49 quit(0 if fails == 0 else 1)