XR Depth Kick is a focused WebXR prototype whose depth-based kick recognizer emits exactly one of:
kick | reject
The shared recognizer detects target-local physical contact, excludes contacts explained by either tracked hand, captures a bounded episode, and scores generic physical evidence without labels, profiles, or per-user calibration. When body tracking is granted, tracked leg motion must corroborate the contact; when it is not granted, recognition falls back to depth and hand evidence.
The application contains five scenarios: Stationary, Room Spawn, Moving, Boxer, and Soccer Goal. The first three use one circular kick pad. Boxer uses independent depth masks for its left and right leg zones, plus native hand-joint punch detection for its head, neck, arms, and torso. Punches and kicks trigger authored reaction animations through separate input paths.
Soccer Goal places a virtual ball on the semantic floor in front of the user. An accepted kick launches it into a bounded Rapier simulation containing a procedural goal and kinematic goalkeeper. Contact speed and target-local contact evidence control a constrained shot trajectory; the scenario reports goal, save, or miss, then automatically resets the ball. Reset Ball is also available from the desktop and XR controls.
Requires Node.js 22 or newer.
npm install
npm run devThe IWSDK CLI opens the managed development runtime at https://localhost:4173, injects Meta Quest 3 IWER, and starts its managed browser. Use npm run dev:status to verify browserCommandReady, or npm run dev:plain to bypass IWSDK and the app's fallback emulator.
The root URL runs the same product UI in every environment. Development builds install embedded IWER only when no existing WebXR runtime is present; production requires a native device runtime such as Quest Browser.
Run npx iwsdk adapter sync --tools copilot to generate the optional,
machine-local .vscode/mcp.json that exposes iwsdk-runtime and
iwsdk-reference to Copilot. This ignored file must not be committed because it
can contain machine-specific paths. VS Code prompts for MCP tool approval
separately. Initialize reference search once with npm run reference:warmup.
Append ?dev=1 or ?debug=1 to show the Boxer leg-probe spheres. They are
hidden during normal use. In XR, HIDE collapses the world-space control panel
to a persistent MENU button.
npm ci
npm run buildThe build writes a minified, self-contained static site to release/. It uses
relative asset URLs, so the directory can be hosted at a GitHub Pages project
path or by any static web server; Vite and Node.js are not required at runtime.
For a local production check, run npm run preview. release/ is a build
output and is not committed. Rapier physics is emitted as a separate chunk that
loads only when Soccer Goal is first selected.
The Deploy GitHub Pages workflow builds and publishes release/ on pushes to
main or by manual dispatch; Settings > Pages > Source must be set to
GitHub Actions. Asset provenance is recorded in Boxer
asset.
npx playwright install chromium
npm run validateIndividual commands are npm run typecheck, npm run lint, npm test, npm run test:browser, and npm run build.
Unit tests are colocated with their source under src. Cross-module integration
tests live under tests/integration, shared test support lives under
tests/support, and Playwright browser tests live under tests/browser.
- Deterministic contact, episode, hand-exclusion, optional body-motion, and generic scoring behavior.
- Test-only mirrored, hand, motion, spike, overlap, moving-target, and depth-hole cases.
- Deterministic local episode replay.
- Independent Boxer leg masks, front-surface probe placement, authored leg reactions, and native-hand punch-zone routing.
- Headset-relative Boxer approach and retreat with semantic-room endpoint, path, recovery, and sidestep checks.
- Deterministic Soccer Goal launch mapping, goal-plane classification, bounded physics, goalkeeper saves, score updates, and automatic reset.
- World-space scenario selection, Safety Override, panel hide/restore, and debug-only leg cues.
- IWSDK-managed Meta Quest 3 IWER rendering, browser screenshot capture, and a clean managed-browser console.
iwsdk-runtimebridge readiness and initializediwsdk-referencesemantic search.- Embedded npm-IWER and injected pre-existing WebXR runtime selection in the isolated Playwright suite.
- Desktop/mobile browser operation, nonblank WebGL output, and XR session restart.
The isolated browser suite does not load the Immersive Web Emulator Chrome
extension. Its pre-existing-runtime case injects a test stub, while its emulated
XR case uses the iwer npm package. Emulation validates lifecycle and scenario
behavior, not Quest depth sensing, body-joint quality, or real-world contact
attribution. See docs/known-limitations.md and
docs/quest-test-plan.md.
Clear the physical area, use a soft target, start slowly, and keep another person outside the kicking area during device tests. The app does not capture RGB, persist episodes, or upload sensor data.
The Safety Override is for debugging only. It disables the player-to-target kick-lane check but continues to avoid mapped furniture at the target position. Room scans can be incomplete or inaccurate, so it can still place targets in unsafe locations. Enabling it is at your own risk; to the extent permitted by law, the project maintainers and contributors are not responsible for injury, property damage, or other loss resulting from use of the application or the override. You remain responsible for checking the physical space before every kick.
