- PVSM.RU - https://www.pvsm.ru -

Статья, скорее всего, не расскажет ничего нового тем, кто давно занимается разработкой приложений с фишкой Augmented Reality, но возможно будет полезна тем, кто интересуется этой темой и близок к написанию AR-приложения.
Немного лирического отступления – что такое AR и почему она стала так популярна на мобильных устройствах.
Когда-то давно, наверное ещё в начале 80-х годов прошлого века, в военные истребители начали внедрять проекторы, которые проецировали информацию прямо на стекло лобового обзора самолёта. Пилоты очень обрадовались нововведению, т.к. следить за самыми важными показателями таким образом было намного удобнее, чем отрывать взгляд на аналоговые, да пусть даже и цифровые, датчики.
К теме особо не относится, но нам доподлинно известен факт (отец одного из наших сотрудников участвовал в разработке), что в советских Су-27 уже в 1992 году крутились 3D-модельки самолёта с подсветкой узлов. Графический движок был написан на ассемблере, на процессоре то ли в 1 МГц, то ли в 2 МГц. Позже такие же индикаторы пришли и в гражданскую авиацию, и в 1990 году один из инженеров Boeing ввёл само понятие “Augmented Reality”.
Много позже, когда в смартфоны пришёл акселерометр и гироскоп, светлой голове пришла идея соединить их с камерой и OpenGL ES – так родилось множество игр, навигационных помощников, но больше всего бюджета в этом направлении расходуется на маркетинговые и промоушн-приложения. Например, вырезав из журнала бумажный каркас для часов, одев его на руку и посмотрев через камеру телефона, пользователь может “примерить” любую марку часов из тех, что рекламирует журнал.
Теперь чисто техническая часть, те небольшие проблемы, с которыми программист столкнётся на самых популярных мобильных платформах.
Версии iOS для iPhone и iPad очень схожи, хотя и различаются по нескольким параметрам. К таким параметрам относится, к сожалению, то, что в iPad OS окно вывода изображения с камеры (UIImagePicker) – обычный UIView, а в iPhone OS – UIViewController. Если в случае с айпадом всё понятно – управляем и ложим его как и любую другую вьюшку, то в айфоне всё немного сложнее – окно ImagePicker-а обязательно должно быть модальным, а добавление вьюшек поверх камеры возможно только используя параметр cameraOverlayView. Т.е. чтобы добавить некое 3D поверх камеры, нужно сделать следующее:
imagePicker .cameraOverlayView = [[ARView new] autorelease];
Скорее всего, это анахронизм, оставшийся от iOS 3 и ниже. К каким неудобствам это приводит? К целому списку:
В общем, куча костылей – всегда лучше, когда все стандартные классы – это вьюшки, а вью контроллерами распоряжается только пользователь.
С Android дела обстоят немного иначе.
Превью камеры, точнее SurfaceView, можно поместить во вьюшку любых размеров, и нет необходимости создавать какую-то модальную активити поверх всего. Но без специфичных телодвижений не обошлось. Оказалось, что мы сами должны найти подходящий размер превью (список размеров иногда большой, и может различаться на девайсах от разных производителей, да что там, даже от одного производителя). В поисках оптимального разрешения и пропорции придется перебирать все размеры из возможных вариантов и сравнивать их с размером и пропорцией вью, куда мы хотим поместить это превью в рантайме. Размер превью не всегда будет соответствовать размеру SurfaceView, так что для соблюдения пропорций картинки и получения подходящего размера превью придется делать свой ViewGroup, размещать там SurfaceView, и делать расчеты, что и как размещать в методе onLayout.
Ещё одна интересная вещь — если в iOS ты хочешь нарисовать 3D модельку поверх превьюшки с камеры, то ты снизу располагаешь превьюшку (UIImagePicker), а дальше сверху рисуем любые вьюшки, в том числе и с 3D моделями. В Android решили сделать как-то по своему — если стандартные UI элементы можно спокойно рисовать поверх превьюшки (SurfaceView), то 3D модельки в GLSurfaceView нужно размещать под(!) превьюшкой. При этом нужно выполнить ряд телодвижений:
Для работы AR этого достаточно, но сразу же возникли проблемы со статическим фоном для non-AR режима. Видите ли, по умолчанию GLSurfaceView не прозрачный, под ним нельзя что-либо отобразить средствами стандартного UI (ни виджет ImageVIew, ни даже background самого GLSurfaceView не работают). Но его можно сделать прозрачным с помощь метода setZOrderOnTop(true) — GLSurfaceView становится прозрачным, но при это начинает отображаться поверх всех элементов в активити.Без разницы — они под, над или вообще в другой вьюшке. Так что выход только один — если что-то нужно рисовать под 3D моделькой, и это не превью с камеры, то нам в помощь OpenGL ES. Для этого нужно загрузить картинку в память как текстуру, предварительно ресайзнув её для получения сторон, кратных степени двойки (на некоторых GPU работает без этого с- или без падения производительности; на некоторых вообще не работает, так что делать нужно обязательно). Выводиться эта текстура будет на плоскости, размеры которой равны размерам вью порта. Нам остается только рассчитать правильную пропорцию текстуры, т.к. есть множество различных размеров экрана с различными пропорциями.
Скриншот в начале статьи взят из приложения Euro Horn, которое посвящено Евро-2012 и доступно для скачивания в AppStore [1] и Google Play [2] (бесплатное с рекламой, хотя реклама почти никогда не показывается в пределах СНГ – так что считайте без рекламы). 3D-модель футбольной дудки выводится поверх фона или, опционально, камеры, и наклоняется вместе в наклоном девайса пользователя, создавая иллюзию настоящей футбольной дудки.
Автор: iago
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/ios/9110
Ссылки в тексте:
[1] AppStore: http://itunes.apple.com/us/app/euro-horn/id527167411?mt=8
[2] Google Play: https://play.google.com/store/apps/details?id=com.rembros.eurohorn
Нажмите здесь для печати.