feat(viz): bold body skeleton strokes
CI build oscope-of / build-check (push) Has been cancelled

Metal lines are 1px and the skeleton was barely visible in
performance. Each ARKit bone is now drawn in concentric offset passes
(SKEL_LINE_WIDTH, default 4 approx px; 1 restores the thin look).
This commit is contained in:
L'électron rare
2026-07-02 18:57:36 +02:00
parent 7b039fbb78
commit 69c560dfe6
3 changed files with 23 additions and 2 deletions
+5
View File
@@ -45,6 +45,7 @@ VIZ_HUD "0" bool show debug HUD overlay
VIZ_SOURCE_KEYS "0" bool wxcvbn + 0-9 source-bundle shortcuts (off: perf safety) VIZ_SOURCE_KEYS "0" bool wxcvbn + 0-9 source-bundle shortcuts (off: perf safety)
VIZ_AUDIO_KEYS "0" bool qsdfghjkl audio-scene shortcuts (off: perf safety; m stays) VIZ_AUDIO_KEYS "0" bool qsdfghjkl audio-scene shortcuts (off: perf safety; m stays)
VIZ_DEFAULT_MODE "auto" str fixed boot viz mode (e.g. voronoi); disables auto-openpos VIZ_DEFAULT_MODE "auto" str fixed boot viz mode (e.g. voronoi); disables auto-openpos
SKEL_LINE_WIDTH "4" int body skeleton stroke width, approx px (1 = thin)
IPHONE_OSC_PORT 57128 int UDP port for iPhone ARBodyTracker /body3d/kp IPHONE_OSC_PORT 57128 int UDP port for iPhone ARBodyTracker /body3d/kp
CONCERT_MIRROR "1" bool mirror video horizontally (!=0 = True) CONCERT_MIRROR "1" bool mirror video horizontally (!=0 = True)
ICP_FUSION "0" bool enable ICP LiDAR fusion (only "1" = True) ICP_FUSION "0" bool enable ICP LiDAR fusion (only "1" = True)
@@ -147,6 +148,9 @@ class VizConfig:
# appear). A fixed mode also DISABLES the auto-openpos timer so it is # appear). A fixed mode also DISABLES the auto-openpos timer so it is
# truly always on (user request live 2026-07-02: t/voronoi permanent). # truly always on (user request live 2026-07-02: t/voronoi permanent).
viz_default_mode: str = "auto" viz_default_mode: str = "auto"
# Approximate body-skeleton stroke width in pixels (multi-pass offsets;
# Metal lines are 1px). 1 = thin historical look.
skel_line_width: int = 4
# ---- iPhone OSC ------------------------------------------------------ # ---- iPhone OSC ------------------------------------------------------
iphone_osc_port: int = 57128 iphone_osc_port: int = 57128
@@ -297,6 +301,7 @@ class VizConfig:
viz_source_keys=_bool_std("VIZ_SOURCE_KEYS", False), viz_source_keys=_bool_std("VIZ_SOURCE_KEYS", False),
viz_audio_keys=_bool_std("VIZ_AUDIO_KEYS", False), viz_audio_keys=_bool_std("VIZ_AUDIO_KEYS", False),
viz_default_mode=_str("VIZ_DEFAULT_MODE", "auto"), viz_default_mode=_str("VIZ_DEFAULT_MODE", "auto"),
skel_line_width=_int("SKEL_LINE_WIDTH", 4),
iphone_osc_port=_int("IPHONE_OSC_PORT", 57128), iphone_osc_port=_int("IPHONE_OSC_PORT", 57128),
concert_mirror=_bool_ne0("CONCERT_MIRROR", True), concert_mirror=_bool_ne0("CONCERT_MIRROR", True),
# ICP_FUSION / MULTIHMR_AUTOCAST use strict "1" convention # ICP_FUSION / MULTIHMR_AUTOCAST use strict "1" convention
+13 -2
View File
@@ -171,6 +171,7 @@ class MetalRenderer(NSObject):
# future iPhone app build flips it. # future iPhone app build flips it.
self._hand_swap_lr = _cfg.hand_swap_lr self._hand_swap_lr = _cfg.hand_swap_lr
self._arkit_full = _cfg.arkit_full_skeleton self._arkit_full = _cfg.arkit_full_skeleton
self._skel_width = max(1, int(_cfg.skel_line_width))
self._init_skel_cpu_buffer() self._init_skel_cpu_buffer()
self._init_mesh_cpu_buffer() self._init_mesh_cpu_buffer()
self._build_pipelines() self._build_pipelines()
@@ -432,11 +433,21 @@ class MetalRenderer(NSObject):
valid = ~fmask valid = ~fmask
elif len(valid) == len(fmask): elif len(valid) == len(fmask):
valid = valid & ~fmask valid = valid & ~fmask
# Bold strokes: Metal lines are 1px, so each bone is drawn
# in concentric offset passes (SKEL_LINE_WIDTH approx px).
_w = getattr(self, "_skel_width", 1)
_o = 1.0 / max(1, s.height or 720)
_offsets = [(0.0, 0.0)]
for _r in range(1, _w):
_d = _r * _o
_offsets += [(_d, 0.0), (-_d, 0.0), (0.0, _d), (0.0, -_d)]
for (ax, ay, bx, by) in arkit_segments( for (ax, ay, bx, by) in arkit_segments(
arr2d, valid, parents, max_len=self._arkit_bone_max arr2d, valid, parents, max_len=self._arkit_bone_max
): ):
if not push_seg(ax, ay, bx, by, 1.0, pid): for _dx, _dy in _offsets:
break if not push_seg(ax + _dx, ay + _dy,
bx + _dx, by + _dy, 1.0, pid):
break
if self._mp_bones is not None and ( if self._mp_bones is not None and (
s.persons_body or s.persons_face or s.persons_hands or s.persons_body or s.persons_face or s.persons_hands or
+5
View File
@@ -425,3 +425,8 @@ def test_viz_default_mode():
assert VizConfig.from_env({}).viz_default_mode == "auto" assert VizConfig.from_env({}).viz_default_mode == "auto"
assert VizConfig.from_env( assert VizConfig.from_env(
{"VIZ_DEFAULT_MODE": "voronoi"}).viz_default_mode == "voronoi" {"VIZ_DEFAULT_MODE": "voronoi"}).viz_default_mode == "voronoi"
def test_skel_line_width_default():
assert VizConfig.from_env({}).skel_line_width == 4
assert VizConfig.from_env({"SKEL_LINE_WIDTH": "1"}).skel_line_width == 1