ipin-vr/vr-poc/README.md
Oskar Kapala cc3d066854 feat(vr-poc): Phase 1 scaffold — native OpenXR passthrough + quad panel
NDK/C++ NativeActivity, arm64-v8a, Gradle 8.12 + AGP 8.7.3 + CMake 3.22.1.

Implementacja (main.cpp):
- EGL headless PBuffer context (wymagany przez OpenXR GLES binding)
- xrCreateInstance z XR_FB_passthrough + XR_KHR_opengl_es_enable
- xrCreateSession → XrGraphicsBindingOpenGLESAndroidKHR
- XR_FB_passthrough: xrCreatePassthroughFB / xrCreatePassthroughLayerFB
  (dynamiczne PFN, graceful fallback gdy extension niedostępna)
- Quad swapchain 512×256 — statyczny ciemnoniebieski panel 80×40 cm,
  1 m przed użytkownikiem (przygotowany pod stb_truetype w fazie 5)
- Pętla klatek: xrWaitFrame / xrBeginFrame / [passthrough + quad] / xrEndFrame
- environmentBlendMode = OPAQUE (passthrough przez warstwę FB_passthrough)

Brakujące pliki SDK (nie w git, lista w vr-poc/README.md):
- libs/arm64-v8a/libopenxr_loader.so   — z Meta OpenXR Mobile SDK
- ovr_sdk/OpenXR/Include/openxr/*.h    — nagłówki OpenXR

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 15:33:27 +02:00

148 lines
4.9 KiB
Markdown

# vr-poc — Phase 1: passthrough + quad panel (native OpenXR, Quest 3)
Natywna apka C++/NDK, arm64-v8a. Renderuje passthrough + jeden statyczny panel
przed użytkownikiem. Brak LLM, brak TTS — czysty baseline do pomiaru FPS.
Szczegóły architektury: `../docs/POC_VR_SPEC.md`.
---
## Wymagane pliki SDK
Przed `./gradlew assembleDebug` musisz zainstalować toolchain i wrzucić dwa
zestawy plików. Poniżej dokładna lista — bez tych plików build nie przejdzie.
### 1. Android SDK + NDK + CMake
Zainstaluj przez Android Studio (SDK Manager) lub `sdkmanager`:
```bash
# Jeśli masz sdkmanager (cmdline-tools):
sdkmanager "platforms;android-35" \
"build-tools;35.0.0" \
"ndk;27.2.12479018" \
"cmake;3.22.1"
```
Oczekiwane lokalizacje (domyślna instalacja Linux):
```
~/Android/Sdk/platforms/android-35/
~/Android/Sdk/build-tools/35.0.0/
~/Android/Sdk/ndk/27.2.12479018/
~/Android/Sdk/cmake/3.22.1/
```
Następnie skopiuj `local.properties.template``local.properties`
(plik jest w `.gitignore`):
```bash
cp local.properties.template local.properties
# Upewnij się że sdk.dir wskazuje na Twój Android/Sdk
```
### 2. Meta OpenXR Mobile SDK — headery
Pobierz **Meta OpenXR Mobile SDK** z:
> https://developer.oculus.com/downloads/package/oculus-openxr-mobile-sdk/
Aktualnie testowana wersja: **v71** (lub nowsza).
Po pobraniu i rozpakowaniu skopiuj **dokładnie te 4 pliki**:
| Źródło w archiwum SDK | Cel w projekcie |
|--------------------------------------------------|-----------------------------------------------------|
| `OpenXR/Include/openxr/openxr.h` | `ovr_sdk/OpenXR/Include/openxr/openxr.h` |
| `OpenXR/Include/openxr/openxr_platform.h` | `ovr_sdk/OpenXR/Include/openxr/openxr_platform.h` |
| `OpenXR/Include/openxr/openxr_platform_defines.h`| `ovr_sdk/OpenXR/Include/openxr/openxr_platform_defines.h` |
| `OpenXR/Include/openxr/openxr_reflection.h` | `ovr_sdk/OpenXR/Include/openxr/openxr_reflection.h`|
Szybko przez jeden `cp -r`:
```bash
SDK_DIR=~/Downloads/ovr_sdk_mobile_openxr_v71 # dopasuj nazwę folderu
cp "$SDK_DIR"/OpenXR/Include/openxr/openxr*.h \
/home/oskar/projects/ipin-vr/vr-poc/ovr_sdk/OpenXR/Include/openxr/
```
### 3. Meta OpenXR Mobile SDK — loader `.so`
Z tego samego archiwum SDK skopiuj **loader** do `libs/arm64-v8a/`:
| Źródło w archiwum SDK | Cel w projekcie |
|--------------------------------------------------------------------------|----------------------------------------|
| `OpenXR/Libs/Android/arm64-v8a/Release/libopenxr_loader.so` | `libs/arm64-v8a/libopenxr_loader.so` |
```bash
cp "$SDK_DIR"/OpenXR/Libs/Android/arm64-v8a/Release/libopenxr_loader.so \
/home/oskar/projects/ipin-vr/vr-poc/libs/arm64-v8a/
```
Ten plik musi być w **dwóch miejscach** (albo możesz zrobić symlink):
- `libs/arm64-v8a/libopenxr_loader.so` — dla Gradle (pakuje do APK jako `lib/arm64-v8a/`)
- CMakeLists.txt czyta go z tej samej lokalizacji do linkowania
---
## Build i deploy
```bash
cd vr-poc/
# Weryfikacja: upewnij się że te pliki istnieją
ls libs/arm64-v8a/libopenxr_loader.so
ls ovr_sdk/OpenXR/Include/openxr/openxr.h
# Build APK (debug)
./gradlew assembleDebug
# Install na Quest 3 (włącz Developer Mode, podłącz USB)
adb install -r app/build/outputs/apk/debug/app-debug.apk
# Logi z apki
adb logcat -s ipin-vr-poc
```
APK output: `app/build/outputs/apk/debug/app-debug.apk`
---
## Weryfikacja Phase 1 (Definition of Done)
- [ ] `./gradlew assembleDebug` — SUCCESS
- [ ] `adb install` — wchodzi na urządzenie
- [ ] Apka startuje w passthrough (widać świat przez kamery)
- [ ] Pływający ciemnoniebieski panel widoczny ~1 m przed użytkownikiem
- [ ] OVR Metrics Tool pokazuje ≥ 72 FPS (brak stale frames)
Obserwacja FPS: uruchom OVR Metrics Tool na urządzeniu przed startem apki.
---
## Struktura kodu
```
vr-poc/
app/
CMakeLists.txt # CMake: native_app_glue + openxr_loader + ipin_vr_poc
src/main/
AndroidManifest.xml # NativeActivity, com.oculus.feature.PASSTHROUGH
cpp/
main.cpp # Cały OpenXR: EGL + passthrough + quad layer
res/values/strings.xml
libs/
arm64-v8a/
libopenxr_loader.so # [WRZUĆ TU — patrz §2/§3 powyżej]
ovr_sdk/
OpenXR/Include/openxr/ # [WRZUĆ TU headery — patrz §2 powyżej]
```
---
## Następne fazy (wg POC_VR_SPEC.md §12)
| Faza | Co dodajemy |
|------|-------------------------------------------------------|
| 2 | llama.cpp worker, generacja na trigger (log tok/s) |
| 3 | CPU affinity konfigurowalna, pomiar wpływu na FPS |
| 4 | sherpa-onnx + Oboe TTS |
| 5 | stb_truetype — tekst polecenia na panelu |
| 6 | Soak 15 min, logowanie, wykres FPS/temp |