Poly API: получение 3D-ресурсов для ваших приложений VR и AR Android

Автор: Peter Berry
Дата создания: 14 Lang L: none (month-012) 2021
Дата обновления: 4 Май 2024
Anonim
Как стать разработчиком VR и AR. Марафон по VR и AR
Видео: Как стать разработчиком VR и AR. Марафон по VR и AR

Содержание


У вас есть отличная идея для мобильного приложения Виртуальная реальность (VR) или Дополненная реальность (AR), но вы не знаете, как воплотить свое видение в жизнь?

Если вы не являетесь разработчиком Android, а также опытным 3D-художником, то создание всех ресурсов, необходимых для обеспечения полного погружения в 360 градусов, может быть непростым процессом.

Просто потому, что у вас нет времени, ресурсов или опыта, необходимых для создания 3D-моделей, не значит, вы не можете создать отличное мобильное приложение VR или AR! В World Wide Web имеется широкий спектр 3D-ресурсов, а также все API, инфраструктуры и библиотеки, необходимые для загрузки и визуализации этих ресурсов в приложениях Android.

Читать дальше: Теперь вы можете посетить любой веб-сайт, используя Daydream VR. Даже этот.

В этой статье мы рассмотрим Poly, онлайн-репозиторий и API, который предоставляет вам тысячи 3D-ресурсов. К концу этой статьи вы создадите приложение, которое извлекает актив 3D Poly во время выполнения, а затем отображает его с помощью популярной библиотеки Processing for Android.


Отображение 3D-активов с помощью Poly

Если вы когда-нибудь баловались разработкой Unity, то репозиторий Poly похож на Unity Asset Store - за исключением того, что все в Poly бесплатно!

Многие из 3D-моделей Poly публикуются под лицензией Creative Commons, поэтому вы можете свободно использовать, изменять и смешивать эти активы, если вы предоставляете создателю соответствующий кредит.

Все 3D-модели Poly разработаны для совместимости с Google VR и AR-платформами, такими как Daydream и ARCore, но вы можете использовать их где угодно и как угодно - потенциально вы можете даже использовать их с Apple ARKit!

Когда дело доходит до извлечения и отображения активов Poly, у вас есть два варианта. Во-первых, вы можете загрузить ресурсы на свой компьютер, а затем импортировать их в Android Studio, чтобы они поставлялись вместе с вашим приложением и соответствовали размеру APK, или вы можете получить эти ресурсы во время выполнения с помощью Poly API.


Кроссплатформенный Poly API на основе REST обеспечивает программный доступ только для чтения к огромной коллекции 3D-моделей Poly. Это сложнее, чем связывание ресурсов с вашим APK, но есть несколько преимуществ для извлечения активов Poly во время выполнения, особенно это помогает контролировать размер вашего APK, что может повлиять на количество людей, загружающих ваше приложение.

Вы также можете использовать Poly API, чтобы предоставить своим пользователям более широкий выбор, например, если вы разрабатываете мобильную игру, вы можете позволить своим пользователям выбирать из целого ряда моделей персонажей.

Поскольку вы можете изменять модели Poly, вы можете даже позволить своим пользователям настраивать выбранный ими персонаж, например, изменяя цвет волос или глаз или комбинируя его с другими активами Poly, такими как различное оружие и броня. Таким образом, Poly API может помочь вам предоставить впечатляющий набор 3D-ресурсов с широкими возможностями для персонализации опыта - и все это для сравнительно небольшой работы. Ваши пользователи будут уверены, что вы потратили массу времени, тщательно продумав все эти 3D-модели!

Создание проекта 3D моделирования

Мы собираемся создать приложение, которое извлекает конкретный актив Poly при первом запуске приложения, а затем отображает этот актив в полноэкранном режиме по запросу пользователя.

Чтобы помочь нам получить этот актив, я буду использовать Fuel, сетевую библиотеку HTTP для Kotlin и Android. Начните с создания нового проекта с настройками по вашему выбору, но при появлении запроса выберите «Включить поддержку Kotlin».

Все вызовы, которые вы совершаете в Poly API, должны содержать ключ API, который используется для идентификации вашего приложения и применения ограничений использования. Во время разработки и тестирования вы часто будете использовать неограниченный ключ API, но если у вас есть какие-либо планы по выпуску этого приложения, то вы должны использовать ключ API с ограничением Android.

Чтобы создать закрытый ключ, вам нужно знать сертификат подписи SHA-1 вашего проекта, поэтому давайте теперь получим следующую информацию:

  • Выберите вкладку «Gradle» в Android Studio (где курсор расположен на следующем скриншоте). Откроется панель «Проекты Gradle».

  • На панели «Проекты Gradle» дважды щелкните, чтобы развернуть «root» своего проекта, а затем выберите «Задачи> Android> Отчет о подписи». Это откроет новую панель в нижней части окна Android Studio.
  • Нажмите кнопку «Переключить выполнение задач / текстовый режим» (где курсор расположен на следующем снимке экрана).

Панель «Выполнить» теперь будет обновляться для отображения большого количества информации о вашем проекте, включая отпечаток SHA-1.

Создайте аккаунт Google Cloud Platform

Чтобы получить необходимый ключ API, вам потребуется учетная запись Google Cloud Platform (GPC).

Если у вас нет учетной записи, вы можете подписаться на 12-месячную бесплатную пробную версию, перейдя на бесплатную страницу Try Cloud Platform и следуя инструкциям. Обратите внимание, что требуется кредитная или дебетовая карта, но в соответствии со страницей «Часто задаваемые вопросы» она используется только для подтверждения вашей личности, и «вам не нужно платить или выставлять счета во время бесплатной пробной версии».

Получите ваш ключ API Poly

После того, как вы все зарегистрировались, вы можете включить Poly API и создать свой ключ:

  • Пройдите к консоли GCP.
  • Выберите значок с подкладкой в ​​верхнем левом углу и выберите «API & Services> Dashboard».
  • Выберите «Включить API и сервисы».
  • В меню слева выберите «Другое».
  • Выберите карту «Poly API».
  • Нажмите кнопку «Включить».
  • Через несколько секунд вы попадете на новый экран; откройте боковое меню и выберите «API & Services> Credentials».

  • В следующем всплывающем окне выберите «Ограничить ключ».
  • Дайте вашему ключу отличительное имя.
  • В разделе «Ограничения приложений» выберите «Приложения Android».
  • Выберите «Добавить имя пакета и отпечаток».
  • Скопируйте / вставьте отпечаток SHA-1 вашего проекта в поле «Отпечаток сертификата подписи».
  • Введите имя пакета вашего проекта (оно отображается в вашем манифесте и вверху каждого файла класса).
  • Нажмите «Сохранить».

Теперь вы попадаете на экран «Учетные данные» вашего проекта, который содержит список всех ваших ключей API, включая ключ API с поддержкой Poly, который вы только что создали.

Зависимости проекта: расширения Fuel, P3D и Kotlin

Для извлечения и отображения активов Poly нам понадобится рука помощи из некоторых дополнительных библиотек:

  • Топливо. В настоящее время у Poly нет официального инструментария Android, поэтому вам придется работать с API напрямую, используя его интерфейс REST. Чтобы упростить этот процесс, я буду использовать сетевую библиотеку Fuel HTTP.
  • Обработка для Android. Я буду использовать рендерер P3D этой библиотеки для отображения актива Poly.

Откройте файл build.gradle вашего проекта и добавьте эти две библиотеки как зависимости проекта:

зависимости {реализация fileTree (include:, dir: libs) реализация "org.jetbrains.kotlin: kotlin-stdlib-jre7: $ kotlin_version" реализация com.android.support:appcompat-v7:27.1.1 // Добавить библиотеку Fuel / / creation com.github.kittinunf.fuel: fuel-android: 1.13.0 // Добавить механизм обработки для Android // реализация org.p5android: processing-core: 4.0.1}

Чтобы сделать наш код более кратким, я также буду использовать расширения Kotlin для Android, поэтому давайте добавим этот плагин, пока у нас открыт файл build.gradle:

применить плагин: kotlin-android-extensions

Наконец, поскольку мы получаем ресурс из Интернета, нашему приложению требуется разрешение на доступ в Интернет. Откройте свой манифест и добавьте следующее:

Добавление вашего ключа API

Каждый раз, когда наше приложение запрашивает ресурс у Poly, оно должно содержать действительный ключ API. Я использую текст-заполнитель, но вы должен замените этот заполнитель своим собственным ключом API, если приложение когда-либо будет работать.

Я также добавляю чек, чтобы приложение отображало предупреждение, если вы забудете заменить текст «INSERT-YOUR-API-KEY»:

import android.os.Bundle import android.support.v7.app.AppCompatActivity class MainActivity: AppCompatActivity () {сопутствующий объект {const val APIKey = "INSERT-YOUR-API-KEY"} переопределяет fun onCreate (saveInstanceState: Bundle?) { super.onCreate (saveInstanceState) setContentView (R.layout.activity_main) // Если ключ API начинается с «INSERT» ... // if (APIKey.startsWith ("INSERT")) {//, затем отобразите следующий тост… .// Toast.makeText (это, «Вы не обновили свой ключ API», Toast.LENGTH_SHORT) .show ()} else {... ... ...

Извлечение актива

Вы можете выбрать любой ресурс на сайте Google Poly, но я буду использовать эту модель планеты Земля.

Вы извлекаете ресурс, используя его идентификатор, который появляется в конце фрагмента URL (выделено на предыдущем снимке экрана). Мы объединяем этот идентификатор ресурса с хостом Poly API, который называется «https://poly.googleapis.com/v1».

import android.content.Intent import android.os.Bundle import android.support.v7.app.AppCompatActivity import android.widget.Toast import com.github.kittinunf.fuel.android.extension.responseJson import com.github.kittinunf.fuel .httpDownload import com.github.kittinunf.fuel.httpGet import kotlinx.android.synthetic.main.activity_main. * import java.io.File class MainActivity: AppCompatActivity () {сопутствующий объект {const val APIKey = "INSERT-YOUR-API -KEY "val assetURL =" https://poly.googleapis.com/v1/assets/94XG1XUy10q "} переопределить fun onCreate (saveInstanceState: Bundle?) {Super.onCreate (saveInstanceState) setContentView (R.layout.activity_main) if ( APIKey.startsWith ("INSERT")) {Toast.makeText (это, «Вы не обновили свой ключ API», Toast.LENGTH_SHORT) .show ()} else {

Далее нам нужно сделать GET-запрос к URL-адресу ресурса, используя метод httpGet (). Я также указываю, что тип ответа должен быть JSON:

import android.content.Intent import android.os.Bundle import android.support.v7.app.AppCompatActivity import android.widget.Toast import com.github.kittinunf.fuel.android.extension.responseJson import com.github.kittinunf.fuel .httpDownload import com.github.kittinunf.fuel.httpGet import kotlinx.android.synthetic.main.activity_main. * import java.io.File class MainActivity: AppCompatActivity () {сопутствующий объект {const val APIKey = "INSERT-YOUR-API -KEY "val assetURL =" https://poly.googleapis.com/v1/assets/94XG1XUy10q "} переопределить fun onCreate (saveInstanceState: Bundle?) {Super.onCreate (saveInstanceState) setContentView (R.layout.activity_main) if ( APIKey.startsWith ("INSERT")) {Toast.makeText (это, «Вы не обновили свой ключ API», Toast.LENGTH_SHORT) .show ()} else {// Выполните вызов сервера, а затем передайте данные, используя Метод «listOf» // assetURL.httpGet (listOf («ключ» для APIKey)). ResponseJson {запрос, ответ, результат -> // Сделать что-то с ответом // result.fold ({val as set = it.obj ()

Актив может иметь несколько форматов, таких как OBJ, GLTF и FBX. Нам нужно определить, что актив находится в формате OBJ.

На этом этапе я также извлекаю имя и URL-адрес всех файлов, которые нам нужно загрузить,
включая основной файл ресурса («корень»), а также любые связанные файлы материалов и текстур («ресурсы»).

Если наше приложение не сможет получить ресурс правильно, оно отобразит всплывающее уведомление пользователя.

import android.content.Intent import android.os.Bundle import android.support.v7.app.AppCompatActivity import android.widget.Toast import com.github.kittinunf.fuel.android.extension.responseJson import com.github.kittinunf.fuel .httpDownload import com.github.kittinunf.fuel.httpGet import kotlinx.android.synthetic.main.activity_main. * import java.io.File class MainActivity: AppCompatActivity () {сопутствующий объект {const val APIKey = "INSERT-YOUR-API -KEY "val assetURL =" https://poly.googleapis.com/v1/assets/94XG1XUy10q "} переопределить fun onCreate (saveInstanceState: Bundle?) {Super.onCreate (saveInstanceState) setContentView (R.layout.activity_main) if ( APIKey.startsWith ("INSERT")) {Toast.makeText (это, «Вы не обновили свой ключ API», Toast.LENGTH_SHORT) .show ()} else {// Выполните GET-запрос к URL-адресу ресурса // assetURL. httpGet (listOf ("ключ" для APIKey)). responseJson {запрос, ответ, результат -> // Что-то сделать с ответом // result.fold ({val asset = it.obj () var objectURL: String? = null var materialLibraryName: String? = null var materialLibraryURL: String? = null // Проверка формата ресурса с использованием массива «форматов» // val assetFormats = asset.getJSONArray («format») // Перебираем все форматы // для (от i до 0 до assetFormats.length ()) { val currentFormat = assetFormats.getJSONObject (i) // Использование formatType для определения типа формата этого ресурса. Если формат OBJ… .// if (currentFormat.getString ("formatType") == "OBJ") {//...then, чтобы получить корневой файл этого ресурса, то есть файл OBJ // objectURL = currentFormat. getJSONObject ("root") .getString ("url") // Извлекаем все зависимости корневого файла // materialLibraryName = currentFormat.getJSONArray ("resources") .getJSONObject (0) .getString ("lativePath ") materialLibraryURL = currentFormat.getJSONArray ("resources") .getJSONObject (0) .getString ("url") break}} objectURL !!. httpDownload (). destination {_, _ -> Файл (filesDir, "globeAsset.obj")} .response {_ , _, result -> result.fold ({}, {// Если вы не можете найти или загрузить OBJ-файл, а затем отобразить ошибку // Toast.makeText (this, «Невозможно загрузить ресурс», Toast.LENGTH_SHORT ) .show ()})} materialLibraryURL !!. httpDownload (). destination {_, _ -> Файл (filesDir, materialLibraryName)} .response {_, _, результат -> result.fold ({}, {Toast. makeText (это, «Невозможно загрузить ресурс», Toast.LENGTH_SHORT) .show ()})}}, { Toast.makeText (это, «Невозможно загрузить ресурс», Toast.LENGTH_SHORT) .show ()})}}}

На этом этапе, если вы устанавливаете проект на своем смартфоне или планшете Android или Android Virtual Device (AVD), ресурс будет успешно загружен, но приложение на самом деле его не отобразит. Давайте исправим это сейчас!

Создание второго экрана: добавление навигации

Мы собираемся отобразить ресурс в полноэкранном режиме, поэтому давайте обновим наш файл main_activity.xml, добавив в него кнопку, которая при нажатии запускает полноэкранный режим.

Теперь давайте добавим onClickListener в конец файла MainActivity.kt:

import android.content.Intent import android.os.Bundle import android.support.v7.app.AppCompatActivity import android.widget.Toast import com.github.kittinunf.fuel.android.extension.responseJson import com.github.kittinunf.fuel .httpDownload import com.github.kittinunf.fuel.httpGet import kotlinx.android.synthetic.main.activity_main. * import java.io.File class MainActivity: AppCompatActivity () {сопутствующий объект {const val APIKey = "INSERT-YOUR-API -KEY "val assetURL =" https://poly.googleapis.com/v1/assets/94XG1XUy10q "} переопределить fun onCreate (saveInstanceState: Bundle?) {Super.onCreate (saveInstanceState) setContentView (R.layout.activity_main) if ( APIKey.startsWith ("INSERT")) {Toast.makeText (это, "Вы не обновили свой ключ API", Toast.LENGTH_SHORT) .show ()} else {assetURL.httpGet (listOf ("ключ" для APIKey)). responseJson {запрос, ответ, результат -> result.fold ({val asset = it.obj () var objectURL: String? = null var materialLibraryName: String? = null var materialLibraryURL: Str ING? = null val assetFormats = asset.getJSONArray ("format") для (от i до 0 до assetFormats.length ()) {val currentFormat = assetFormats.getJSONObject (i) if (currentFormat.getString ("formatType") == "OBJ" ) {objectURL = currentFormat.getJSONObject ("root") .getString ("url") materialLibraryName = currentFormat.getJSONArray ("resources") .getJSONObject (0) .getString ("lativePath ") materialLibraryURL = currentFormat.getJSONArray (" resources " ) .getJSONObject (0) .getString ("url") break}} objectURL !!. httpDownload (). destination {_, _ -> Файл (filesDir, "globeAsset.obj")} .response {_, _, результат -> result.fold ({}, {Toast.makeText (это, «Невозможно загрузить ресурс», Toast.LENGTH_SHORT) .show ()})} materialLibraryURL !!. httpDownload (). destination {_, _ -> File (filesDir, materialLibraryName)} .response {_, _, result -> result.fold ({}, {Toast.makeText (this, «Невозможно загрузить ресурс», Toast.LENGTH_SHORT) .show ()})}}, {Toast.makeText (это, «Невозможно загрузить ресурс», Toast.LENGTH_SHORT) .sh ow ()})} // Реализация кнопки // displayButton.setOnClickListener {val intent = Intent (this, SecondActivity :: class.java) startActivity (intent); }}}

Построение 3D холста

Теперь давайте создадим действие, в котором мы будем отображать наш актив в полноэкранном режиме:

  • Удерживая клавишу Control, щелкните файл MainActivity.kt вашего проекта и выберите «Создать> Файл / Класс Kotlin».
  • Откройте раскрывающийся список «Вид» и выберите «Класс».
  • Дайте этому классу имя «SecondActivity», а затем нажмите «ОК».

Чтобы нарисовать 3D-объект, нам нужен 3D-холст! Я собираюсь использовать рендерер P3D библиотеки Processing для Android, что означает расширение класса PApplet, переопределение метода settings () и затем передачу P3D в качестве аргумента методу fullScreen (). Нам также необходимо создать свойство, которое представляет актив Poly как объект PShape.

личное развлечение displayAsset () {val canvas3D = object: PApplet () {var polyAsset: PShape? = null override fun settings () {fullScreen (PConstants.P3D)}

Затем нам нужно инициализировать объект PShape, переопределив метод setup (), вызвав метод loadShape (), а затем передав абсолютный путь к файлу .obj:

override fun setup () {polyAsset = loadShape (File (filesDir, "globeAsset.obj"). absolutePath)}

Рисование на холсте P3D

Чтобы нарисовать на этом трехмерном холсте, нам нужно переопределить метод draw ():

переопределить забавный draw () {background (0) shape (polyAsset)}}

По умолчанию многие ресурсы, извлеченные из Poly API, находятся на меньшей стороне, поэтому, если вы сейчас запустите этот код, вы можете даже не увидеть актив, в зависимости от конфигурации экрана. При создании 3D-сцен вы обычно создаете пользовательскую камеру, чтобы пользователь мог исследовать сцену и просматривать ваши 3D-активы с полных 360 градусов. Однако это выходит за рамки данной статьи, поэтому я буду изменять размер и положение актива вручную, чтобы обеспечить его удобное размещение на экране.

Вы можете увеличить размер актива, передав отрицательное значение в метод scale ():

шкала (-10f)

Вы можете настроить положение актива в виртуальном трехмерном пространстве, используя метод translate () и следующие координаты:

  • ИКС. Располагает актив вдоль горизонтальной оси.
  • Y. Располагает актив вдоль вертикальной оси.
  • З. Это ось «глубина / высота», которая превращает 2D-объект в 3D-объект. Положительные значения создают впечатление, что объект приближается к вам, а отрицательные значения создают впечатление, что объект удаляется от вас.

Обратите внимание, что преобразования являются кумулятивными, поэтому все, что происходит после функции, накапливает эффект.

Я использую следующее:

перевести (-50f, -100f, 10f)

Вот законченный код:

override fun draw () {background (0) scale (-10f) translate (-50f, -100f) // Рисуем актив, вызывая метод shape () // shape (polyAsset)}}

Далее нам нужно создать соответствующий файл макета, в который мы добавим 3D-холст как виджет FrameLayout:

  • Удерживая клавишу Control, щелкните папку «res> layout» вашего проекта.
  • Выберите «Файл ресурсов макета».
  • Дайте этому файлу имя «activity_second», а затем нажмите «ОК».

Теперь у нас есть FrameLayout «asset_view», нам нужно сообщить об этом нашей SecondActivity! Вернитесь к файлу SecondActivity.kt, создайте новый экземпляр PFragment и укажите его в направлении нашего виджета asset_view:

import android.os.Bundle import android.support.v7.app.AppCompatActivity import kotlinx.android.synthetic.main.activity_second. * import processing.android.PFragment import processing.core.PApplet import processing.core.PConstants import processing.core .PShape import java.io.File class SecondActivity: AppCompatActivity () {переопределить fun onCreate (saveInstanceState: Bundle?) {Super.onCreate (saveInstanceState) setContentView (R.layout.activity_second) displayAsset ()} личное веселье displayAsset () {val canvas3D = object: PApplet () {var polyAsset: PShape? = null переопределить забавные настройки () {fullScreen (PConstants.P3D)} переопределить забавные настройки () {polyAsset = loadShape (File (filesDir, globeAsset.obj "). absolutePath)} переопределить забавные draw () {background (0) scale (-10f) translate (-50f, -100f) shape (polyAsset)}} // Добавить следующий // val assetView = PFragment (canvas3D) assetView.setView (asset_view, this)}}

Последний шаг - добавление SecondActivity в ваш манифест:

// Добавить следующее //

Тестирование вашего проекта

Теперь мы готовы протестировать готовый проект! Установите его на устройство Android или AVD и убедитесь, что у вас есть активное подключение к Интернету. Как только приложение запустится, оно загрузит ресурс, и вы сможете просмотреть его, нажав кнопку «Показать актив».

Вы можете скачать этот полный проект с GitHub.

Завершение

В этой статье мы рассмотрели, как использовать Poly API для извлечения 3D-ресурса во время выполнения и как отобразить этот актив с помощью библиотеки Processing for Android. Считаете ли вы, что Poly API может сделать разработку VR и AR доступной для большего количества людей? Дайте нам знать в комментариях ниже!

Связанный

  • Google представит приложения AR для «сотен миллионов» устройств Android в 2018 году
  • Google научит вас искусственному интеллекту и машинному обучению бесплатно
  • 15 лучших VR-игр для Google Cardboard
  • 10 лучших VR-приложений для Google Cardboard
  • Что такое Google Фуксия? Это новый Android?
  • Что такое дуплекс Google? - функции, дата выпуска и многое другое
  • Как создать VR-приложение для Android всего за 7 минут
  • Мобильные гарнитуры VR - каковы ваши лучшие варианты?

Uber-совместная компания Uber выпустила форму ценных бумаг -1 в преддверии предстоящего публичного IPO. Документ -1, поданный в Комиссию по ценным бумагам и биржам США, дает некоторые интересные сведе...

Главные новости Apple на этой неделе касаются слухов об обновлении iPad Pro, которое предположительно появится этой осенью.MacRumor попал в руки физический макет, который дает нам довольно четкое пред...

Популярное на сайте