Commit Graph
5 Commits
Author SHA1 Message Date
DeeJanuzandClaude Opus 5.5 9029a2d7a5 hands: drawn hands blend between frames, hold still when lost, refuse jumps
User, 2026-10-13: "implement interpolation for the rendered hands so that they
feel smoother", and "if the hand is lost it's preferable the rendered hand
display freeze instead of make impossible movements, spaz out, or vanish until a
few seconds have passed".

screens/handhold.h, per side in ft-handview:
- each tracking frame blends in joint by joint from the drawn pose over about
  the frame interval (15-70 ms), drawn every 15 ms meanwhile;
- a lost hand stays frozen where it was drawn for HANDS_VIEW_HOLD s (3);
- a frame 15 cm / 6 m/s off the last one taken, or with the palm turned over,
  waits for two agreeing frames (or 0.25 s) while the drawn hand holds still;
  a first-seen or returning hand waits for two agreeing frames too.
HANDS_VIEW_SMOOTH=0 gives the old behaviour. Tests in handview_test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 17:30:41 -06:00
DeeJanuzandClaude Opus 5.5 f16ad59a92 ft-handview: a robot hand built from the skeleton (HANDS_VIEW_MODEL=robot)
A stylized robot hand made in code, no asset: rigid pieces, each fixed to
one bone, so nothing bends or stretches out of shape. A light shell per
finger bone (a tapered box with rounded edges and ends), dark balls at the
knuckles and the thumb's base, dark hinges at the other joints, a palm of a
dark core between a palm plate and a back plate with panel lines, and a
short closed cuff past the wrist. Cyan accents glow: fingertip pads, a line
across the knuckles, a dot in the palm, a ring round the cuff. solid is
ceramic white over dark grey metal; ghost is pale and see-through.

screens/handrobot.cpp builds one mesh (2373 vertices, 4360 triangles) once,
a right hand on DemoPose's open hand, in 16 segments' frames. The frames are
handskin's rule (new handskin::TrackedFrames); a left hand's are a right
one's mirrored, so the same mesh draws it mirrored. Each vertex is fixed to
its bone's start or end: shells keep their rounded ends, the straight middle
takes up the tracked length, fingertips end at the tracked tips. The vertex
shader applies one segment's matrix per vertex; no cap pass (it's closed).

Cost (--snapshot, frame-job 4 cores, same run): robot 0.21-0.24 ms CPU and
0.55-0.57 ms GPU wait per draw, against asset 0.28/0.66, babylon 0.26/0.66,
mrtk3 0.25/0.66.

Tests: segments start at their joints along their bones, no vertex past its
bone's length, fingertips at the tracked tips, left = right mirrored vertex
for vertex, rigid segments across poses, only the middle stretches with a
longer bone, accents on the right sides.

No free robot hand asset fit; screens/assets/hands/README.md says what was
looked at.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 13:51:50 -06:00
DeeJanuzandClaude Opus 5.5 366f5efa4c ft-handview: a cleaner look, a capped wrist, and four more hand models
The look: no more drawn outline. The old rim pass lit a hard line wherever the
hand met the background or a part of it further back, so a finger over the palm
got scratchy white lines. Now the body pass keeps only the surface nearest the
eye (depth) and writes how squarely it faces the eye, the fade, a light from
above and how near a fingertip; the second pass turns that into a soft fresnel
rim, a slight fingertip glow and an antialiased outline. ghost glows white
toward its edges; solid is lit from above with a soft cool rim.

The wrist: the model is cut open where the fade ends, so a hand pointing away
showed its inside (a hollow tube, a fist's fingertips through the palm). A
stencil pass counts front faces up and back faces down along each view (on its
own, with the depth test off: early depth would drop hidden ones); where a view
went in through the cut, a disc where the fade begins covers it.

The models: HANDS_VIEW_MODEL=asset (generic-hand, still the default) | babylon
(Babylon.js, CC BY 4.0) | mrtk3 (BSD-3-Clause, right only, mirrored) | godot
(Godot XR Tools, CC0) | mrtk2 (MIT) | capsules. Each is in
screens/assets/hands/<name>/ with its licence and a README giving the source
commit, hashes and conversion (the MRTK ones were FBX: assimp, then the new
screens/tools/hand-glb-clean.py). hand-asset.py maps each skeleton onto WebXR's
25 joints by name and writes them all into handasset.h; handskin takes the
model's index.

Cost (--snapshot, asset): CPU 0.34 ms per draw (was 0.32-0.33), GPU wait
0.61-0.62 ms per draw (was 0.57). --snapshot now prints the GPU wait.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 13:26:31 -06:00
DeeJanuzandClaude Opus 5.5 3a7a532cb9 ft-handview: your hands as a 3D hand model, with Room View on too
The rendered hands are now the WebXR Input Profiles' generic hand (MIT),
posed by the tracked skeleton and skinned on the GPU: per joint a frame
from the bone and the palm, scaled to the hand and each bone's length.
Two looks, HANDS_VIEW_STYLE=ghost|solid; HANDS_VIEW_MODEL=capsules keeps
the tube hand. With HANDS_VIEW_ROOMVIEW=1 (the default) the hands also
float over the cutout with Room View on. --snapshot draws demo poses
into a PNG without SteamVR, and the cost (0.4 ms a draw, the tubes 0.6).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 12:44:29 -06:00
DeeJanuzandClaude Opus 5.5 3d1eee828a ft-handview: your hands drawn over games, the dashboard and the void with Room View off
Quest-style: a see-through light hand from the tracked skeleton with a bright
rim, fading out behind the wrist, over everything. Each hand is a placed,
side-by-side overlay facing the head, so it stays put as the head turns and
redraws only as the hand moves. Hidden while a hand holds a controller (the
pointer helper's word, now also on @ft_handview). frametop-handview.service
runs it; nothing installs it yet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 11:24:28 -06:00