Merge branch 'worktree-agent-a07f1b74ffe22c320'
# Conflicts: # HANDOFF.md
This commit is contained in:
commit
b5e7241ac1
11 files changed
+1281
-315
No files matched your search
@@ -147,32 +147,45 @@ device only; the editor has an XR simulator for dev. Trackers/action map: see `x
|
||||
(bool actions unreliable across runtimes). Engine logs land in
|
||||
`~/.local/share/godot/app_userdata/VR Messs/logs/godot.log` — agents: read this after user
|
||||
playtests instead of guessing.
|
||||
- **UI direction — physical prop controls first**: buttons, knobs, sliders as real 3D objects
|
||||
(touch interaction, later Box3D for feel). Godot has NO native world-space widget system —
|
||||
`Control`s are screen-space; world UI is always Control-rendered-into-3D via `SubViewport`
|
||||
(optionally `SubViewportCompositionLayer` for XR-native sharpness/perf). Use at most one
|
||||
SubViewport/composition-layer screen for dense content (file browser, settings) if needed;
|
||||
everything else is props. World-space text is native and cheap: `Label3D` (SDF, crisp at
|
||||
distance) and `TextMesh` (extruded) — no SubViewport required.
|
||||
- **`WorldPanel.cs` is the first prop-UI prototype**: summoned/dismissed via `ax_button` (A/X —
|
||||
- **UI direction — physical prop controls first, ONE dense screen**: buttons, knobs, sliders
|
||||
as real 3D objects where they live in the world (touch interaction, later Box3D for feel).
|
||||
Godot has NO native world-space widget system — `Control`s are screen-space; world UI is
|
||||
always Control-rendered-into-3D via `SubViewport` (optionally `SubViewportCompositionLayer`
|
||||
for XR-native sharpness/perf). At most ONE SubViewport/composition-layer screen for dense
|
||||
content — **that screen is now the in-VR menu (`WorldPanel`, below)**; everything else is
|
||||
props. World-space text is native and cheap: `Label3D` (SDF, crisp at distance) and
|
||||
`TextMesh` (extruded) — no SubViewport required.
|
||||
- **`WorldPanel.cs` = the in-VR menu (2026-10-02, replaced the chunky prop-knob panel)**:
|
||||
real Godot Control UI (`MainMenu.cs`: tabs Player / World / System, normal-sized buttons,
|
||||
slider, scrollable log, FPS) rendered by `MenuScreen.cs` into a 960×640 SubViewport shown on
|
||||
a thin 0.36×0.24 m panel (~2.7 px/mm ≈ 1:1 with headset pixels at 45 cm — viewport textures
|
||||
have no mipmaps, so don't oversample). Summoned/dismissed via `ax_button` (A/X —
|
||||
menu_button belongs to the runtime). It is PARENTED UNDER `XROrigin3D` — Koikatsu-VR-style
|
||||
"fixed in the player's room": IRL movement doesn't move it relative to you, game locomotion
|
||||
carries it. If that feel is wrong, reverting = reparenting to `Main` and fixing the `_Ready`
|
||||
node paths. Floats in front of the summoning hand facing the player (full 3D facing — works
|
||||
from lying poses), draggable directly or via laser at fixed ray distance while gripped
|
||||
(continuously re-orients toward the head). The Spawn
|
||||
knob also recalls the panel in front of the head. The pointer
|
||||
tip is a protruding stylus cone (apex ~12 cm ahead of the controller) and is THE cursor:
|
||||
knobs hover-highlight and PRESS ON CONTACT (tip within 4.5 cm, with cooldown) — physical
|
||||
buttons, no trigger needed; trigger still presses laser-hovered knobs (knobs are
|
||||
laser-targetable). Presses play a synthesized click (code-generated `AudioStreamWav` PCM
|
||||
— no asset). Spawn/Ping/Close knobs. Locomotion defers
|
||||
node paths. Appears 0.3 m in front of the summoning hand facing the head (full 3D facing —
|
||||
works from lying poses), draggable by grip directly or via laser at fixed ray distance
|
||||
(continuously re-orients toward the head); "Return to spawn" recalls it in front of the head.
|
||||
**Input = the touch-first hybrid cursor, injected as mouse events**: each frame both
|
||||
controller rays are projected onto the panel plane (analytic, no physics query), converted to
|
||||
SubViewport pixels and pushed with `Viewport.PushInput(event, true)`
|
||||
(`InputEventMouseMotion`/`InputEventMouseButton`, `NotifyMouseEntered/Exited`). The stylus
|
||||
tip (12 cm ahead of the controller) within 6 cm of the surface = TOUCH cursor: crossing
|
||||
0.6 cm presses, backing out past 1.8 cm releases (hysteresis; entering from the side/behind
|
||||
never presses) — buttons fire on release like a real tap, sliders drag while touching.
|
||||
Farther away = LASER cursor, trigger clicks/drags (edge-triggered: a trigger already held
|
||||
never clicks). Thumbstick Y while hovering = mouse wheel (scroll containers). One Godot mouse
|
||||
per viewport → one owning hand (press holder ≻ touching hand ≻ laser). Cursor dot per hand
|
||||
(shrinks as the tip nears = proximity cue), haptic tick on press, synthesized click
|
||||
(code-generated `AudioStreamWav`, no asset). Menu actions run DEFERRED (never from inside
|
||||
the injected event). "Recalibrate body" calls `Recalibrate()` on the first node in group
|
||||
`"calibration"` (disabled when absent — the menu never creates it; `Calibration.cs` provides it). Locomotion defers
|
||||
grab/teleport to the panel when a hand is near it (`WorldPanel.IsBlocking`). Laser lines are
|
||||
owned by `Locomotion.UpdatePointer`: shown only when aiming at something interactive (marker
|
||||
or panel) AND beyond `LaserMinDistance` (0.35 m) — near targets are touched via the pointer
|
||||
tip instead, which is the touch-first hybrid cursor in miniature. Grab deltas and turn
|
||||
pivots are computed in WORLD space (tracking-space math made two-hand turns orbit the map
|
||||
center — do not regress this).
|
||||
owned by `Locomotion.UpdatePointer`: for the menu it asks `WorldPanel.TryGetLaserDistance`
|
||||
(beam only while that hand is in laser mode, beyond `LaserMinDistance` 0.35 m); markers keep
|
||||
the raycast path. Regression: `scenes/menu_spike.tscn` "MENU: overall PASS". Grab deltas
|
||||
and turn pivots are computed in WORLD space (tracking-space math made two-hand turns orbit
|
||||
the map center — do not regress this).
|
||||
- **Control scheme is deliberate**: decide what lives on controllers vs. what lives in menus
|
||||
before stacking bindings — controller button budget is scarce, menus carry the rest.
|
||||
|
||||
@@ -189,8 +202,9 @@ device only; the editor has an XR simulator for dev. Trackers/action map: see `x
|
||||
movement weird, teleport + lasers broken (owner report 2026-10-01; experiments, not
|
||||
current issues). Fix-or-replace deferred — owner's candidate replacement is physics
|
||||
thumbstick movement if the body-physics track lands.
|
||||
4. ~~UI: first prop panel~~ — **done** (`WorldPanel.cs`); SubViewport/composition-layer screen
|
||||
deferred until dense content (file browser) is actually needed.
|
||||
4. ~~UI: first prop panel~~ — **done** (`WorldPanel.cs`), then REPLACED (2026-10-02, owner:
|
||||
knobs "incredibly chonky") by the SubViewport menu screen (`MenuScreen` + `MainMenu`) —
|
||||
the one allowed dense screen. Awaiting owner playtest.
|
||||
5. ~~Box3D validation spike~~ — **done, PASS** (drop+contact, velocity-chase vs wall, headless
|
||||
via `scenes/physics_spike.tscn`).
|
||||
6. **Physics hands & props sandbox — grab v5.3 = SOLVER-OWNED RIGID WELD (patched addon).**
|
||||
@@ -223,8 +237,8 @@ device only; the editor has an XR simulator for dev. Trackers/action map: see `x
|
||||
(Nimso/VRChat precedent); props/floor/table mask 1|3|4|5, hands 4/1|4, chest 3/1|3,
|
||||
arm segments 5/1; panel stays 2/0 (props pass
|
||||
through even when shown); layers live on
|
||||
CollisionObject3D, NOT CollisionShape3D. Panel = prop-UI prototype (ax_button summon,
|
||||
contact-press knobs, Reset). Laser/distant grab REMOVED (user never knew it existed);
|
||||
CollisionObject3D, NOT CollisionShape3D. Panel = the in-VR menu (ax_button summon,
|
||||
touch/laser Control UI, Reset props). Laser/distant grab REMOVED (user never knew it existed);
|
||||
grab = palm-proximity only, per-hand palm-face offset (left +X, right −X — taste).
|
||||
PinJoint quirks (anchors captured at creation; joint node position READ every tick;
|
||||
break measures the prop-local anchor vs the palm point) apply to the v5.0–5.2 PIN path
|
||||
|
||||
Reference in new issue
Block a user