Кулуари VR. Бібліотеки для перегляду панорам 360*



Всім привіт! VR нині у тренді, тема злободенна, різних проектів і способів реалізовувати відображення тривимірної картинки, здається, скоро буде мільйон. Сьогодні у нас в гостях Михайло Вайсман, засновник компанії по розробці мобільних додатків Trinity Digital. Він зголосився розповісти про роботу з бібліотеками для відображення 360-градусних панорам, за що ми висловлюємо йому вдячність. Гаразд, ви всі прийшли сюди за цікавим досвідом, а не за контентом до ката. ;)


Що тут відбувається?
Привіт, Хабр! Представити мене вже встигли, але правила є правила. Я — Михайло Вайсман. Досвід роботи з VR я набув, працюючи в Trinity Digital над проектом Airpano Virtual Travel разом з командою Doubble. Airpano — додаток з можливістю перегляду VR фото — і видеопанорам. В процесі роботи я зіткнувся з проблемою: тема VR вже не перший рік в тренді, але готових бібліотек, що дозволяють якісно відобразити VR контент, немає. Довелося вибирати між написанням з нуля власного рішення і застосуванням того, що вже є на ринку. Вибрали компромісний варіант — взяти наявне на ринку open source рішення і доопрацьовувати під наші цілі. У последного варіанту є свої плюси, але й про мінуси забувати не варто. Ми спробували три бібліотеки, і ось що з цього вийшло:

Krpano — бібліотека на основі WebView
Ми почали роботу з варіанту, реалізованого на основі WebView — з бібліотеки krpano. Причиною вибору стали:

  • Швидка можливість інтеграції в проект;
  • Декларація підтримки всіх Android пристрої з версією не нижче 4.2;
  • Універсальність рішення, можливість перевикористання для різних платформ.


В реальності з бібліотекою krpano все виявилося не настільки райдужно, тому що у krpano браузерний движок. Почати можна хоча б з того, що не на всіх пристроях є сучасні движки хрому, які можуть максимально ефективно реалізовувати можливості даної бібліотеки. Більшість не самих топових пристроїв працювали повільно з панорамами виключно через використання webview, а на частині з них бібліотека і зовсім не працювала. В якості потенційного рішення ми спробували інтегрувати в додаток движки від Chrome і Firefox (спочатку один, потім інший — для тестів). В якійсь мірі це допомогло. Працювала дана штука скрізь, от тільки…

У підсумку додаток займало понад 100 мегабайт — і це не наші файли або код, а бібліотека, плюс браузерний движок у проекті. Найприкріше, що навіть ці збочення не допомогли значно оптимізувати якість і швидкість роботи — вони залишалися на непримлемо низькому рівні. Вирішальним мінусом krpano стала необхідність програмувати на рівні xml-конфігурацій (подібне конфігурування проходить довго і збільшує ціну розробки для кожної панорами).

PanoramaGL — бібліотека на основі OpenGL
Після місяця спроб (або тортур) з krpano, перепробувавши кілька видів бібліотек, ми зупинилися на panoramagl — це бібліотека працювала швидше інших, і не володіла тими критичними вадами, які ми виявили в krpano. Плюс Panoramagl виявився простішим у впровадженні і підтримував роботу на найслабкіших пристроях.

Але і тут не обійшлося без недоліків: наприклад, в panorama gl була реалізація тільки на основі activity. Нам довелося її переписувати, додавати підтримку фрагментів.

Крім відсутності підтримки фрагментів, panoramagl знайшлося безліч функцій, потребують адаптації і переписування — щоб забезпечити підтримку наших завдань: наприклад, стерео режим для підтримки cardboard в panoramagl не реалізований. При цьому інтегрувати Cardboard SDK в PanoramaGL неможливо — з-за того, що останній використовує OpenGL.

Зате з допомогою даної либы досить просто зробити базову, не зовсім коректну версію стерео режиму — картинка просто дублюється на дві частини екрану, без зсуву лівій частині щодо правої.

Так виглядає коректно реалізований стерео-режим — права картинка сдивнута щодо лівої:



А ось так виглядає стерео-режим, реалізований нами на основі бібліотеці PanoramaGL — права картинка ідентична лівої, зсуву між картинками немає:



Бібліотека Panframe від mindlight
Ще в процесі доопрацювання напилком panoramagl у нас з'явилася необхідність додати відео контент в додаток. У panoramagl такої можливості немає, і ми знову постали перед дилемою: написати самим бібліотеку для відображення відео контенту, або використовувати готове рішення. Зупинилися на умовно-платного бібліотеці Panframe.

Обрали її за підтримку відео — і фотопанорам «з коробки», а також за хорошу швидкість роботи відео — і фотопанорам. Все нормально працювала навіть на типових «среднячках», не кажучи вже про флагманах. Працювати з нею — одне задоволення.

Використовуємо бібліотеку для відображення відео



1. Вказуємо permission:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>


2. Ініціалізуємо view:

PFView vrView = PFObjectFactory.view(this); //для відображення однієї камери. в якості параметру передається activity
PFView vrView = PFObjectFactory.vr(this); //для відображення двох камер з ефектом лінз для окулярів. в якості параметру передається activity. працює в ландшафтній орієнтації
PFAsset asset = PFObjectFactory.assetFromUri(this, Uri.parse(filename), this); //у якості параметрів передається: контекст, шлях до відео, інтерфейс PFAssetObserver для отримання подій завантаження контенту
vrView.displayAsset(asset); //указыаем контент для відображення
viewContainer.addView(vrView.getView(), 0); //додаємо view На layout. viewContainer — ViewGroup з layout
asset.play();//запускаємо відображення вмісту


Список аргументів простий:
PFView — view об'єкт з 360 контентом;

PFAssetObserver містить сигнатуру методу onStatusMessage c двома параметрами:

PFAsset — інтерфейс контенту з сигнатурами керуючих методів:
  • void play();
  • void stop();

  • void pause();
  • float getPlaybackTime();
  • void setPLaybackTime(float var1);
  • float getDuration();
  • String getUrl();
  • PFAssetStatus getStatus();
  • int getDownloadProgress();
  • void release();
  • void setVolume(float var1);


Ще є PFAssetStatus — enum з набором статусів:
  • LOADED;
  • PLAYING;
  • PAUSED;
  • STOPPED;
  • COMPLETE;
  • DOWNLOADING;
  • DOWNLOADED;
  • DOWNLOADCANCELLED;
  • ERROR;
  • BUFFERING;
  • BUFFERFULL.


Приклад відображення зображення

З панорамними фото все також непогано, просто замість PFAsset досить використовувати метод injectImage(Bitmap image) або injectImageFromResource(int id)
При цьому якщо задати setMode() з типом 1, дані не будуть відображені:

vrView = PFObjectFactory.view(this);
vrView.injectImageFromResource(R. raw.geysers_1);
container.addView(vrView.getView(), 0);


Також бібліотека підтримує анімовані hotspot'и:
PFHotspot hp = vrView.createHotspot(BitmapFactory.decodeResource(getResources(), R. raw.hotspot)); //R. raw.hotspot — id зображення hotspot'а
hp.setCoordinates(60, 40, 0);
hp.setClickListener(this); //в якості параметру передається об'єкт, який реалізує інтерфейс PFHotspotClickListener

PFHotspot — інтерфейс з сигнатурами методів для управління
void setEnabled(boolean var1);
void setSize(float var1);
void setCoordinates(float var1, float var2, float var3); полярні координати в градусах
void setTag(int var1);
int getTag();
void setClickListener(PFHotspotClickListener var1);
void animate(); //анімує hotspot анімація пульсування

PFHotspotClickListener — простий інтерфейс з методом onclick з параметром PFHotspot


Дещо ще

У PFView є метод setMode з наступними параметрами:
mode:
0 — сферична панорама;
1 — плоске зображення;
2 — для двох камер (для vr не треба вказувати окремо).

aspect: The aspect ratio (пропорції) контенту для плоского зображення.

setFormat:
0 — сферична панорама;
1 — top-down formatted сферична панорама

Для вказівки методу навігації (гіроскоп або тач) використовується метод vrView.setNavigationMode з параметром PFNavigationMode:

MOTION — навігація з гіроскопом
TOUCH — навігація тачем


З явних мінусів: исходники бібліотеки обфусцированы — прочитати і розширити функціональність буде загруднительно; зрозуміти текст помилок неможливо. У поєднанні
з повільними відповідями розробника бібліотеки (Ми більше трьох місяців чекали відповідь на питання: «Як додати cardboard-режим») — рішення panframe в якості основної фото і відео бібліотеки в додатку виявилося складним у плані розширення для подальшої експлуатації і вдосконалення продукту.

VR View від Google
Бібліотека для відображення VR контенту від Google була представлена в березні 2016 року. Я з цікавістю стежив за розвитком бібліотеки, і на конференції Google I/O 2016 звернув особливу увагу на лекції по темі VR, а також поговорив з розробниками Google щодо планів розвитку бібліотеки. Інтегрувати бібліотеку в ваш продукт можна наступним чином.

Викачуємо Google VR за цим посиланням:
developers.google.com/vr/android/get-started#using_android_studio
А також забираємо Release notes останніх версій бібліотеки:
developers.google.com/vr/android/release-notes#cardboard_sdk_for_android_v070

Google VR SDK містить кілька aar-бібліотек:
  • audio
  • base
  • common
  • commonwidget
  • controller
  • panowidget
  • videowidget


і кілька sample проектів:
  • controllerclient — приклад для daydream контролера
  • simplepanowidget — приклад використання 360 зображення VrPanoramaView
  • simplevideowidget — приклад використання 360 відео VrVideoView
  • treasurehunt — приклад використання GL сцени через GvrView


Для застосування VrPanoramaView в нашому проекті виконуємо наступні кроки:
  • Імпортуємо бібліотеки: common, commonwidget, panowidget;
  • Додаємо view (com.google.vr.sdk.widgets.pano.VrPanoramaView) в layout;
  • Викликаємо метод VrPanoramaView.loadImageFromBitmap, що приймає в якості аргументів:


Public клас VrPanoramaView успадковується від VrWidgetView і містить VrPanoramaRenderer і VrPanoramaEventListener, public клас VrWidgetView успадковується від FrameLayout і містить GL-сцену і кнопки управління.

Ще нам знадобляться ось ці хлопці:
  • VrPanoramaEventListener, успадкований від VrEventListener, простий клас, що містить кілька методів;
  • onLoadSuccessJni;
  • onLoadErrorJni;
  • onLoadSuccess — якщо Bitmap був успішно завантажено, інакше — onLoadError;
  • onClick;
  • onDisplayModeChanged;


Клас VrPanoramaRenderer з пакетним доступом успадковується від VrWidgetView і реалізує завантаження Bitmap, після чого викликає native arm бібліотеку panorenderer зі складу panowidget.aar.

Public abstract VrWidgetView реалізує інтерфейс Renderer і викликає native методи щодо подій Renderer — інтерфейсу зі складу openGl c сигнатурами методів onSurfaceCreated, onSurfaceChanged, onDrawFrame.

Таким чином можна швидко (три кроки) розгорнути додаток, що підтримує відображення простого растрового (Bitmap) зображення з можливістю перегляду в MONO і STEREO режимі з інтерфейсом Google. Проте, якщо необхідно реалізувати динамічний контент, наприклад, відображення маркерів поверх Bitmap, читання камери, підписатися на renderer події, то VrPanoramaView не надає дані можливості, так що для розширення функціональності вам доведеться правити native бібліотеку panorenderer.

Для нашого проекту в GVR не вистачало підтримки переходу між панорамами через мітки, встановлені на тій чи іншій точки панорам. Розробники VR View пропонують відправляти feature requests на потрібні вам фічі в репозиторій бібліотеки на github. Головна інтрига, чи буде google розвивати бібліотеку на рівень вище, ніж MVP і підтримувати функціональність для складних проектів. Відповіді ми поки не знаємо, але вже зараз можна за 10 хвилин додати добре працюють VR-можливості в ваш проект, рік тому таке важко уявити.

Висновки


Ринок VR бібліотек поки не встигає за попитом, але крига вже скресла, склад вирушив і все таке. Процес не зупинити: розробникам стали доступні перші непогані бібліотеки для технічних завдань VR проекти, готові до використання «з коробки». Нижче — коротке резюме плюсів і мінусів розглянутих рішень:

Бібліотека
Плюси
Мінуси
KRpano
Швидка інтеграція в проект;

Кросплатформеність.
Повільна робота на старих пристроях;

Повна відмова роботи на ряді пристроїв.
PanoramaGL
Щодо швидка інтеграція в проект;

Підтримка не лише базової функціональності, але і, наприклад, переходу між панорамами;

Не погана швидкість роботи панорам на повільних пристроях.

Давно не підтримується (останній комміт був два роки тому);

Некоректна реалізація стерео-режиму;

Відсутність підтримки Cardboard SDK.
Panframe
Підтримка 360-градусних видеопанорам;

Хороша швидкість роботи панорам на повільних пристроях.
Закритість вихідних кодів;

Умовно-платність;

Повільні/отсутсвующие відповіді саппорта.
VR View
Швидка можливість інтеграції;

Базові можливості MVP;

Хороша швидкість роботи панорам на повільних пристроях

Підтримка Google;

Можливість залишити feature request на додавання необхідних функцій.
Бібліотека поки що не підтримує функції, що виходять за рамки MVP

(наприклад, накладення картинки поверх панорами, перехід між панорамами).


Висновки — якщо вам потрібно швидко інтегрувати VR в ваш додаток, будь то специфічно заточений під VR проект, або будь-яке інше додаток, де було б цікаво додати VR — ви можете використовувати VR View від Google.

Якщо у вашому проекті потрібна підтримка складних ефектів і просунутих можливостей (накладення картинки, переходи тощо) — використовуйте конфігурацію Panframe + Panoramagl, але будьте готові до того, що доведеться неабияк попітніти і дописати ці бібліотеки під потреби вашого проекту. Альтернатива — чекати розвитку GVR. Зробіть feature request потрібних функцій — висока ймовірність, що їх додасть або сам Google в наступних релізах, або сторонні розробники, Так як бібліотека викладена, як open source проект.

На цьому все, спасибі за увагу, якщо є питання — задавайте, буду радий відповісти.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.