[feat] roadmap 13 batch D - VR fix pack (D1-D7) - #34
Merged
Conversation
- updateTeleport was the last raw sources.indexOf(source) holdout (194/210 class): after a hands<->controllers swap the inputSources order diverges from the three.js controller slots, so the arc rode the wrong controller - new teleportArcPose(session) resolves the slot via controllerIndexFor with a caller-session fallback for unstamped slots (fake-session tests) - e2e vr-teleport-handedness: arc pose follows the stamp across a slot swap; no right hand -> no arc; existing teleport suites stay green Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- three caches an InstancedMesh boundingSphere for its raycast pre-check; refreshHandleMatrix never invalidated it, so handles re-posed outside the entry-time bounds (object moved, far vertex drag, undo swap) silently stopped ray-picking in VR and on desktop - null boundingSphere/boundingBox on every handle re-pose so the next raycast lazily recomputes; covers tickMeshEdit, applyVerts and undo paths - e2e vr-vertex-handle-bounds: corner handle picks at spawn, still picks after the object moves 50 units, old spot no longer picks Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- obj:prefab now saves the WHOLE selection as one layout-preserving prefab via savePrefabSelection (the U-2 op desktop already uses); single selection keeps the single-object savePrefab path - e2e vr-multi-prefab: two selected objects -> ONE Group prefab with both members; single selection still snapshots a Mesh - known pre-existing: vr-radial-menu exact Edit-ring expectation fails on main too (avatar:possess from the default-on avatar module) - the D4 Edit-ring rework updates that suite Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- counted labels act on the SET: Duplicate/Delete/Save prefab show (N) and run duplicateSelection/deleteSelection/savePrefabSelection (desktop objectMenu parity, U-2) - Make Group takes the Edit Mesh slot for 2+ selected (one-undo groupSelection); Edit Mesh/Ungroup gate on a single selection - entry schema gains disabled(): greyed sector + label, activation blocked at the top of executeVRMenuAction; Properties greys out when multi (primary-only panel would silently edit one member) - the VR palette paints the whole selection set: per-object before map, one composite history entry via the batch API, throttled live colors - VRMenu re-derives sectors on selectedObjects; disabled styling - e2e vr-multiselect-ring (ring swap, counted labels, set duplicate, one-undo group, disabled props); vr-radial-menu expectation now allows module-registered entries (avatar:possess made the exact-join check fail on main - pre-existing) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rface - beamTarget: the beam/reticle now ends on the NEAREST hit among scene objects and any OPEN floating panel (menu/objects/props/prefabs/chat/ settings/approve/edit/snap/keyboard/palette) so navigating menus shows the beam ending in a circle on the hovered control; a panel in front clears the object hover behind it - reticlePose: the ring lays onto the hit surface via the world-space face normal (flipped toward the viewer, nudged 0.004*scale off the surface so it never z-fights), beam-aligned fallback when the hit has no normal - a full circle is visible on spheres/curved faces telling the user exactly where they point - e2e vr-reticle-v2: pose math (flat fallback, floor lay-flat, backface flip, min scale) + nearest-wins panel termination round-trip Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- radial Ping used to fire IMMEDIATELY from the pointer hand, but on a trigger activation that ray is parked on the radial itself, so the ping landed wherever the menu floated. The sector now ARMS a one-shot (vrPingArmed): the ring closes, beam+reticle tint to your ping color, and the NEXT trigger pings the exact pointed x,y,z from the firing controller (firePingIfArmed in Scene's trigger path, before the prefab ghost). A sky miss keeps the arm; reopening the radial cancels it - right-stick ping resolves the POINTER hand (pointerHandIndex) - with the menu on the right hand it pinged where the MENU hand pointed - pingFromController reports whether a ping landed and refuses index -1 - e2e vr-ping-accuracy: arm/fire/miss/cancel round-trip + pointer-hand resolution; ping/ping-v2/ping-highlights suites stay green Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- caps raised: face 300 -> 1000 tris, vertex 500 -> 800 verts, so the default sphere (960 tris / 561 verts) is editable out of the box - both limits are live user-editable stores (vrFaceCap/vrVertexCap, localStorage-persisted) with number rows in Settings > VR; the section now binds settingsSection=vr for deep links - over-limit attempts warn with COUNTED toasts (N of limit) carrying an Open Settings action that lands on the VR section (editCapToast) - all three block sites: enterFaceEdit, the Edit side-menu vertices mode, and the obj:editmesh dense fallback - a GROUP blocking mesh edit now says Ungroup it first / edit each mesh (the common imported-model blocker) in both edit modes - e2e vr-edit-caps (defaults, counted toasts, deep link, persistence, group hint, settings row round-trip); vr-face-edit/vr-vertex-edit updated for the new defaults (+ the face suite meshgeo check now accepts the 12 raw-bytes wire format it had drifted from) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
AlexZ005
added a commit
that referenced
this pull request
Jul 22, 2026
…itions, modules repo - CLAUDE.md map rewritten for flow v2: flowGraphs source-of-truth + editor-view mirror (and WHY it lives in the leaf store), flowGraphs.js/objectFlow.js libs, graph-routed nodesHandler, implicit-owner runtime rule, embed inject/harvest, resolvedInputType/replaceableInputEdges socket rules - new gotchas: the history.js TDZ-cycle family (flowRuntime imports must not reach history/shortcuts statically), NodeWrapper flex-ROW slot + padded-box handle anchoring, autosave GLTF restore re-uuid (userData.__uuid stamp), deselect clears only the selectedObjects SET - Module SDK section: registerNodeDefs + pointerRay (drag recipe) + the theprototype-app/modules repo (flow-toolkit, untangle) - status 2026-07-22: PR #36 + #37 merged, 190 untangle shipped as-built, svelte-check baseline now 499/77, remaining H4 + open PRs #33/#34 - e2e skill: npx vite dev (npm eats --port flags), __stores additions (flowGraphs/flowGraphsCtl/objectFlow/pointerRayNow/applyModuleMessage), repo-external module verification recipe (manager zip install) - peer-feature skill: per-object graph replication rules (graphId, allNodes, prune invariants, flowgraph history kind, single-connection inputs) + SDK additions + untangle as the worked game example Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- the blue wireframe overlay is a LineSegments CHILD of the edited object; three raycasts lines with a 1-WORLD-UNIT threshold, so every objectsGroup raycast (beam/reticle, selection, ping) hit invisible fat lines up to a metre off the surface while vertex-editing. Faces mode was immune because its overlay lives at the scene root - exactly the on-device report. The overlay is now non-raycastable (decorative) - the scene-root vertex HANDLE dots join beamTarget while editing, so the beam/reticle terminate ON the handle you point at (parity with faces mode); a handle hit never highlights an object - e2e vr-vertex-ray: near-miss ray no longer phantom-hits, face ray lands at the true surface distance on the MESH, corner ray terminates on the handle, exit removes the targets Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- new vrNavigationSuppressed() predicate: true while world pan (right grip
on air), two-grip world grab, two-hand object scale, vertex carry
(grip or trigger), face rigid grab, live extrude/inset adjust, a stretch
slider drag or a box-select marquee is active; with {grips:true} it also
covers ANY held grip
- updateVRControls gates teleport + snap-turn on it (grips included - a
held grip always means manipulation) and DISARMS on suppression so a
gesture released mid-stick-deflection cannot fire a queued teleport or
an instant snap; the stick must return to center first
- VRControls.svelte gates left-stick locomotion on the plain predicate;
left-grip + left-stick pan/elevate deliberately stays (it is itself a
locomotion mode), world pan/grab and mesh gestures never also move you
- e2e vr-nav-suppression drives the reachable gestures through their real
entry points (face live-adjust, hold-style vertex carry); grips and
world-pan need a live squeeze loop, so their feel is the on-device check
- test infra: helpers.cjs gains opt-in PEER_CONFIG env (seeds the
peer-server Settings per context) - localhost-origin lanes resolve to a
local :9001 signaling server that is not running, which broke every
two-peer suite; vr-box-select Tools-ring expectation now tolerates the
U-1 Ping entry (stale on main)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Collaborator
Author
|
Three on-device follow-ups pushed (D8-D10), from VR testing feedback:
Also in D9: tests/e2e/helpers.cjs gains an opt-in PEER_CONFIG env (localhost-origin lanes resolve the peer server to a local :9001 that isn't running, which broke every two-peer suite in the worktree), and vr-box-select's Tools-ring expectation now tolerates the U-1 Ping entry (stale on main). Build green + svelte-check 501/77 on each commit; on-device feel of the suppression/ray fixes is the user's check. |
- the stick-click ping routed through the POINTER hand (opposite the menu hand), so with the menu on the right hand a right-stick click sent the ping down the LEFT ray - the on-device report. Pings now always fire from the ACTING hand: the clicked stick hand here, the firing trigger hand for the armed radial ping (already the case) - pointerHandIndex stays for hover targeting; doc updated - e2e vr-ping-accuracy gains an acting-hand check (armed fire from slot 0 follows slot 0 ray even though the pointer hand is slot 1) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Roadmap #13 Batch D - the VR fix pack (D1-D7), one commit per phase.
Fixes
sources.indexOf(source)- the last raw-slot holdout of the 194/210 class. NowteleportArcPose()resolves by the handedness stamp (caller-session fallback for unstamped slots).refreshHandleMatrixnever invalidated the InstancedMesh boundingSphere, so handles re-posed outside the entry-time bounds silently stopped picking. Bounds are nulled on every re-pose (covers tickMeshEdit / applyVerts / undo).Features
obj:prefabsaves a multi-selection as ONE layout-preserving prefab (savePrefabSelection, desktop parity).disabled()entry predicate, activation blocked), and the VR palette paints the whole selection with ONE composite undo entry.Verification
vr-teleport-handedness,vr-vertex-handle-bounds,vr-multi-prefab,vr-multiselect-ring,vr-reticle-v2,vr-ping-accuracy,vr-edit-caps- all green, plus the neighboring suites (teleport/vertex/face/palette/radial/ping/settings) re-run green.vr-radial-menuexact Edit-ring join (avatar:possess from the default-on avatar module) andvr-face-edit's meshgeopositions.length(the Feature/scene-lights #12 raw-bytes wire format).npm run buildgreen after every phase;npx svelte-checkholds the 501/77 baseline.🤖 Generated with Claude Code