Immersive VR Companion Application
Bridging real-time gyroscope head tracking, ML-based hand gesture control, and side-by-side stereoscopic rendering.
FLOW is a state-of-the-art Flutter-based immersive VR companion app. It transforms standard Android smartphones into interactive virtual reality headsets using cardboard-style goggles.
Unlike traditional mobile VR apps that offer passive viewing, FLOW combines Side-by-Side (SBS) stereoscopic video playback with dual-channel gyroscopic head tracking and ML-powered hand tracking (via front/back cameras). This allows users to see their hand skeletons overlaid in real-time on top of the video sphere and control playback through intuitive, hands-free head and hand gestures.
- ๐ถ๏ธ Stereoscopic SBS Viewer: Horizontally tiled eye views with horizontal and vertical translations simulating a 3D VR environment.
- ๐ Dual-Channel Gyroscopic Sensor Processing: Independent damping and sensitivity constants for viewport translation and gesture detection.
- ๐๏ธ MediaPipe Hand Tracking Pipeline: Stream frames from camera, detect 21 landmarks, and paint virtual glowing skeletons inside the VR view.
- ๐ง Gesture Recognition:
- Head Gestures: Tilt head left (seek back), right (seek forward), up (play/pause), or down (toggle telemetry HUD).
- Hand Gestures: Detect finger counts (2 = seek back, 3 = seek forward, 4 = play/pause, 5 = toggle HUD).
- ๐ช Air Touch: Spatial drawing experience using the device's camera and ML-based hand tracking. Users can draw in mid-air using a single finger, change brush colors with 2-4 fingers, and clear the canvas with an open palm.
- ๐ Guided Device Validation: A three-step setup flow checking headset readiness, gyroscopic capability, and camera permissions before entering VR mode.
- ๐บ Native Fallback Launch Path: Optional ExoPlayer implementation rendering spherical 360ยฐ OpenGL surfaces.
- ๐ Pilot Authorization Gate: Restricts usage based on expiration dates and optional device whitelists.
Below is a preview of the animated bootstrapping and startup experience from the loader:
Before jumping into the VR engine, users go through a strict calibration and authorization wizard to ensure their device matches the hardware requirements:
FLOW is built using a modern, scalable feature-first architecture with strict isolation between core libraries, state layers, screens, and Android native integrations.
graph TD
A[main.dart Bootstrap] --> B(Pilot Gate Validation)
B -->|Authorized| C[GoRouter Navigation Graph]
B -->|Expired/Unauthorized| D[Blocking System Dialog]
C --> E[Loader Screen]
E -->|Redirect 2200ms| F[Shell Router Base]
F --> G[Home Dashboard]
F --> H[Setup Wizard]
F --> I[Play Content Library]
F --> J[Profile Stats]
I -->|Play Selection| K[VrImmersiveScreen Engine]
subgraph VrImmersiveScreen Pipeline
K --> L[SBS Video Player]
K --> M[Gyroscope Controller]
K --> N[Camera Image Streamer]
N --> O[MediaPipe ML Detector]
O --> P[Hand Overlay Painter]
end
The primary engine (vr_immersive_screen.dart) runs a loop executing multiple tracking calculations concurrently:
The stereoscopic depth feel is achieved by horizontal and vertical shifting. Left and right views receive a small disparity offset:
The translation is handled inside a custom nested ClipRect + OverflowBox widget hierarchy, which allows clipping oversized videos as a relative window frame.
To avoid conflicts between smooth camera navigation and strict gesture detection thresholds, events are parsed through two distinct filters:
- Control Channel (Gesture Gating): Optimized for damping accidental minor shakes. $$\text{yaw}t = (\text{yaw}{t-1} + \omega_z \times 0.04) \times 0.85$$ $$\text{pitch}t = (\text{pitch}{t-1} + \omega_x \times 0.04) \times 0.85$$
- View Channel (Smooth Camera): Higher sensitivity and gentler decay for natural look-around behavior. $$\text{viewYaw}t = (\text{viewYaw}{t-1} + \omega_z \times 0.06) \times 0.92$$ $$\text{viewPitch}t = (\text{viewPitch}{t-1} + \omega_x \times 0.06) \times 0.92$$
Landmarks returned by the model are mapped using vector thresholds to check extension status:
-
Thumb Extension Rule:
$$\text{isThumbExtended} \iff |x_{\text{tip}} - x_{\text{wrist}}| > |x_{\text{IP}} - x_{\text{wrist}}|$$ -
Fingers Extension Rule (Index, Middle, Ring, Pinky):
$$\text{isFingerExtended} \iff y_{\text{tip}} < y_{\text{PIP}}$$ (Since coordinate space starts at the top-left, a lower Y index represents a vertically higher point)
FLOW introduces Air Touch, an interactive spatial drawing experience using the device's camera and ML-based hand tracking.
- Real-time Camera Streaming: Captures low-resolution YUV420 image streams for optimized hand tracking performance.
- Dynamic ML Hand Detection: Uses
hand_detectionto process frames and map 21 landmarks into a normalized coordinate space, correcting for device orientation changes on the fly. - Intuitive Gestures:
- Draw (1 Finger): Extend your index finger to begin painting dynamic strokes.
- Color Picker (2-4 Fingers): Hold 2, 3, or 4 fingers to switch brush colors seamlessly.
- Clear Canvas (5 Fingers): Open your palm to wipe the drawing space.
- Custom Rendering: Uses an overlay painter pipeline to visualize both skeletal hand structures and user-generated strokes in real-time.
flow/
โโโ android/app/src/main/
โ โโโ kotlin/com/example/flow/
โ โ โโโ MainActivity.kt # Method channel handlers & sensor verification
โ โ โโโ VRPlayerActivity.kt # Native Android Media3 Spherical Video Player
โ โโโ res/layout/
โ โ โโโ activity_vr_player.xml # spherical_gl_surface_view rendering surface
โ โโโ AndroidManifest.xml # Permission locks & Activity registration
โโโ assets/
โ โโโ fonts/ # NASA, Geist, and GeistPixel fonts
โ โโโ images/ # SVGs, animations, and app icons
โโโ lib/
โ โโโ main.dart # App bootstrap and orientation locks
โ โโโ core/
โ โ โโโ constants/ # Centralized strings
โ โ โโโ native/ # VRChannel method interface
โ โ โโโ providers/ # Riverpod providers (pilot, theme, profile)
โ โ โโโ router/ # App navigation configuration
โ โ โโโ theme/ # AppColors, radii, spacings, and theme definitions
โ โโโ features/
โ โ โโโ home/ # Dashboard and quick actions
โ โ โโโ loader/ # Startup splash animation
โ โ โโโ play/ # Immersive video player engine
โ โ โโโ profile/ # User analytics and metrics
โ โ โโโ settings/ # Configurations and theme toggles
โ โ โโโ setup/ # Calibration and test screens
โ โ โโโ shell/ # Bottom navigation shell route layout
โ โโโ shared/widgets/ # Reusable components (GlassPanel, PilotBadge)
โโโ pubspec.yaml # Flutter dependencies declaration
| Package | Version | Purpose |
|---|---|---|
flutter_riverpod |
2.5.1 |
Decoupled reactive state management |
go_router |
13.2.0 |
Declarative deep-linking navigation |
sensors_plus |
6.1.1 |
Gyroscopic motion rate listeners |
hand_detection |
3.0.7 |
MediaPipe model processor interface |
camera |
0.11.0+2 |
Image stream frames pipeline |
shared_preferences |
2.2.3 |
Local persistent cache for step completion |
- Flutter SDK version
โฅ 3.5.0 - Android SDK setup with Min SDK level
23(Marshmallow) - A physical Android device containing a hardware gyroscope sensor and a functional back camera.
- Clone the Repository:
git clone https://github.com/your-username/flow.git cd flow - Fetch Dependencies:
flutter clean flutter pub get
- Run Development Build:
flutter run
- Assemble Release APK:
flutter build apk --release
- ๐จ Barrel Distortion Shaders: Simulating physical fish-eye lenses to compensate for cardboard lenses.
- ๐ Calibration UI: Add screen-space sliders inside the HUD to alter yaw/pitch sensitivities and hand overlay translation multipliers.
- ๐ถ๏ธ 3D Stereoscopic Hand Projection: Translate 2.5D coordinates to complete 3D vectors mapping real depth distances.
- ๐ Cloud Video Library: Stream user-uploaded content directories rather than hardcoded mock feeds.
Made with ๐ฉถ for immersive exploration.


