When entering immersive mode, toolbox and input text view now position themselves relative to the user's initial camera position: - Toolbox: 0.5m ahead, 0.5m below, 0.2m to the left - Input text view: 0.5m ahead, 0.5m below (centered) Uses camera world Y position to ensure vertical offset is consistent regardless of head pitch/tilt when entering XR. Also added CLAUDE.md documentation for the codebase. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
5.0 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
This is "immersive" - a WebXR/VR diagramming application built with BabylonJS and React. It allows users to create and interact with 3D diagrams in both standard web browsers and VR environments, with real-time collaboration via PouchDB sync.
Build and Development Commands
Development
npm run dev- Start Vite dev server on port 3001 (DO NOT USE per user instructions)npm run build- Build production bundle (includes version bump)npm run preview- Preview production build on port 3001npm test- Run tests with Vitestnpm run socket- Start WebSocket server for collaboration (port 8080)npm run serverBuild- Compile TypeScript server codenpm run havok- Copy Havok physics WASM files to Vite deps
Testing
- Run all tests:
npm test - No single test command is configured; tests use Vitest
Architecture
Core Technologies
- BabylonJS 8.x: 3D engine with WebXR support and Havok physics
- React + Mantine: UI framework for 2D interface and settings
- PouchDB: Client-side database with CouchDB sync for collaboration
- Auth0: Authentication provider
- Vite: Build tool and dev server
Key Architecture Patterns
Singleton Scene Management
The application uses a singleton pattern for the BabylonJS Scene via DefaultScene (src/defaultScene.ts). Always access the scene through DefaultScene.Scene rather than creating new instances.
Observable-Based Event System
The application heavily uses BabylonJS Observables for event handling:
- DiagramManager.onDiagramEventObservable: Central hub for diagram entity changes
- DiagramManager.onUserEventObservable: User position/state updates for multiplayer
- AppConfig.onConfigChangedObservable: Application settings changes
- controllerObservable: VR controller input events
Event observers use a mask system (DiagramEventObserverMask) to distinguish:
FROM_DB: Events coming from database sync (shouldn't trigger database writes)TO_DB: Events that should be persisted to database
Diagram Entity System
All 3D objects in the scene are represented by DiagramEntity types (src/diagram/types/diagramEntity.ts):
- Entities have a template reference (e.g.,
#image-template) - Managed by
DiagramManagerwhich maintains a Map ofDiagramObjectinstances - Changes propagate through the Observable system to database and other clients
VR Controller Architecture
Controllers inherit from AbstractController with specialized implementations:
LeftController: Menu interactions, navigationRightController: Object manipulation, selection- Controllers communicate via
controllerObservablewithControllerEventmessages Rigplatformmanages the player rig and handles locomotion
Database & Sync
PouchdbPersistenceManager(src/integration/database/pouchdbPersistenceManager.ts) handles all persistence- Supports optional encryption via
Encryptionclass - Syncs to remote CouchDB via proxy (configured in vite.config.ts)
- URL pattern
/db/public/:dbor/db/private/:dbdetermines database name - Uses
presence.tsfor broadcasting user positions over WebSocket
Project Structure
src/vrcore/: Engine initialization and core VR setupsrc/controllers/: VR controller implementations and input handlingsrc/diagram/: 3D diagram entities, management, and scene interactionsrc/integration/: Database sync, encryption, and presence systemsrc/menus/: In-VR 3D menus (not React components)src/objects/: Reusable 3D objects (buttons, handles, avatars)src/react/: React UI components for 2D interfacesrc/util/: Shared utilities and configurationserver/: WebSocket server for real-time presence
Configuration System
Two configuration systems exist (being migrated):
- AppConfig class (src/util/appConfig.ts): Observable-based config with typed properties
- ConfigType (bottom of appConfig.ts): Legacy localStorage-based config
Settings include snapping values, physics toggles, fly mode, and turn snap angles.
Important Development Notes
Proxy Configuration
The dev and preview servers proxy certain routes to production:
/sync/*- Database sync endpoint/create-db- Database creation/api/images- Image uploads
Physics System
- Uses Havok physics engine (requires WASM file via
npm run havok) - Physics can be enabled/disabled via AppConfig
customPhysics.tsprovides helper functions
WebGPU Support
The engine initializer supports both WebGL and WebGPU backends via the useWebGpu parameter.
Encryption
Databases can be optionally encrypted. The Encryption class handles AES encryption with password-derived keys. Salt is stored in metadata document.
Environment Variables
VITE_USER_ENDPOINT: User authentication endpointVITE_SYNCDB_ENDPOINT: Remote database sync endpoint
Check .env.local for local configuration.