Статьи

Кодирование измерительного приложения с помощью ARKit: объекты и тени

Наряду со многими другими инструментами, которые были сделаны устаревшими с помощью современных технологий, похоже, что следующая рулетка может быть следующей. В этом руководстве мы научимся преодолевать разрыв между реальностью и технологиями, используя дополненную реальность и камеру на вашем устройстве iOS, чтобы создать приложение, которое будет измерять расстояние между двумя точками.

В этом посте мы запустим приложение и закодируем его основные элементы интерфейса. Завтра мы закончим это, измеряя между двумя точками в сцене AR.

Если вы только начинаете работать с ARKit, обязательно ознакомьтесь с моим другим учебником, в котором вы научитесь вносить планету в свой дом, используя дополненную реальность.

  • Дополненная реальность
    Зашифруйте свое первое приложение дополненной реальности с ARKit

Давайте начнем создавать нашу виртуальную линейку, которая позволит нам измерить расстояние между любыми двумя точками реального мира. Если вы подумаете об этом, вам может даже не понадобиться измерительная лента для ежедневных измерений!

Для начала убедитесь, что у вас есть версия Xcode, которая поддерживает ARKit. Затем вам нужно будет сделать новый проект XCode.

Запустите Xcode и нажмите « Создать новый проект XCode».

Рисунок 1. Создание проекта XCode.

Возможно, вы привыкли создавать приложение с одним представлением , но для этого урока вам нужно будет выбрать приложение дополненной реальности и нажать « Далее».

Рисунок 2. Выберите приложение дополненной реальности.

Вы можете назвать свой проект как угодно, но я буду называть мои ARPlanets. Вы также заметите, что внизу есть опция, в которой вы можете выбрать из SceneKit, SpriteKit и Metal. Все это игровые платформы Apple, и для целей данного руководства мы будем использовать SceneKit .

Идите вперед и выберите SceneKit, если он еще не выбран. Ваш экран должен выглядеть примерно так:

Рисунок 3 Создайте свой проект

Поскольку Xcode Simulator не имеет камеры, вам нужно подключить свой iPhone. К сожалению, если у вас нет iPhone, вам необходимо взять его в аренду, чтобы иметь возможность следовать этому руководству (и любым другим приложениям, связанным с камерой или AR). Если у вас уже есть iPhone, подключенный к Xcode, вы можете перейти к следующему шагу.

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

В верхней строке меню выберите « Окно» > « Устройства и симуляторы». В появившемся окне убедитесь, что устройства выбраны сверху.

Теперь подключите устройство с помощью кабеля молнии. Это должно привести к тому, что ваше устройство появится в левой панели окна « Устройства и симуляторы» . Просто щелкните свое устройство и установите флажок Подключаться через сеть .

Рисунок 4 Устройства и симуляторы

Теперь вы сможете выполнять беспроводную отладку на этом iPhone для всех будущих приложений.

Теперь ваша настройка завершена. У вас должно быть работающее приложение ARKit, и вы можете протестировать его на iPhone, который вы только что подключили. В верхнем левом углу Xcode, рядом с кнопками Run и Stop , выберите устройство из симулятора выпадающего списка.

Рисунок 5 Выберите симулятор

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

Космический корабль дополненной реальности

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

Отличная работа по запуску приложения ARKit! Теперь давайте приступим к избавлению от космического корабля и созданию нашего приложения для измерения расстояний с нуля. Наше приложение будет работать, позволяя пользователю размещать две сферы на сцене AR, а затем вычислять расстояние между ними. Как бы просто это ни звучало, для этого требуется немало программирования, поэтому наденьте свою задумчивую шляпу и давайте приступим!

Я не буду объяснять начальный код в этом руководстве, поэтому, если вы чего-то не понимаете, обязательно ознакомьтесь с моим руководством по началу работы с ARKit .

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

Если вы перейдете в папку Assets.xcassets в каталоге вашего проекта, вы увидите два файла, которые составляют ваш космический корабль: ship.scn и texture.png . Это два файла, которые сообщают Xcode, как именно должен выглядеть космический корабль. В нашем приложении мы будем определять сферы программно. Если вам нужно добавить более сложные узлы, можно использовать метод .scn , но если вы можете, всегда лучше делать что-то в коде.

Теперь, когда вы удалили корабельные активы, вы можете получать ошибки в этот момент (если нет, вы будете получать при выполнении кода). Это потому, что все еще есть текущие ссылки на файлы, которые мы удалили. Не беспокойся, хотя. Мы избавимся от этого примера кода, чтобы начать программирование с нуля.

Перейдите в файл ViewController.swift и удалите следующие две строки кода:

1
2
3
4
5
// Set the view’s delegate
sceneView.delegate = self
 
// Show statistics such as fps and timing information
sceneView.showsStatistics = true

После этого ваш viewDidLoad() должен выглядеть следующим образом:

1
2
3
4
5
6
7
8
override func viewDidLoad() {
    super.viewDidLoad()
    // Set the view’s delegate
    sceneView.delegate = self
     
    // Show statistics such as fps and timing information
    sceneView.showsStatistics = true
}

Мы все еще можем использовать их в нашем новом приложении. Оставшийся стартовый код в приложении — это просто шаблон, который выполняет такие вещи, как запуск представления SceneKit и другие подобные вещи.

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

Чтобы создать метку, объявите переменную в верхней части вашего класса следующим образом:

1
var measurementLabel = UILabel()

Здесь мы только что создали экземпляр класса UILabel , и в нашем viewDidLoad() мы можем настроить его различные атрибуты.

Добавьте следующее в ваш viewDidLoad() вверху, чтобы создать фон:

1
2
measurementLabel.frame = CGRect(x: 0, y: 0, width: view.frame.size.width, height: 100)
measurementLabel.backgroundColor = .white

Первая строка здесь устанавливает белый фон для метки, чтобы он был видимым и не сливался с живым представлением сзади. Этот фон будет выровнен по верху и будет иметь высоту 100.

Далее нам нужно установить текст, а также его выравнивание и добавить метку к представлению. Для этого добавьте следующее в ваш viewDidLoad() :

1
2
3
measurementLabel.text = «0 inches»
measurementLabel.textAlignment = .center
view.addSubview(measurementLabel)

Первая строка кода заставляет текст метки по умолчанию сказать «0 дюймов». Кроме того, мы хотим, чтобы приложение выглядело достаточно утонченным, поэтому мы разместим метку на холсте. Наконец, мы добавляем метку к представлению.

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

Мы создаем сферу несколько раз, поэтому нет смысла кодировать ее в viewDidLoad() . Вместо этого давайте создадим метод, который мы сможем использовать и вызывать из любого места. Так что вставьте следующую функцию в ваш проект:

1
2
3
func newSphere(at position: SCNVector3) -> SCNNode {
    // Your code goes here
}

Как видите, мы берем позицию типа SCNVector3 и затем возвращаем SCNNode , который будет сферой. Это не кажется очень важным сейчас, но мы вернемся к тому, почему мы принимаем SCNVector3 как позицию позже.

Давайте теперь начнем фактически создавать сферу. Добавьте следующие три строки в метод newSphere() который вы только что создали:

1
2
3
4
5
6
7
8
// Creates an SCNSphere with a radius of 0.4
let sphere = SCNSphere(radius: 0.01)
 
// Converts the sphere into an SCNNode
let node = SCNNode(geometry: sphere)
 
// Positions the node based on the passed in position
node.position = position

Первая строка кода просто создает сферу типа SCNSphere и устанавливает ее начальный радиус в 0,01 метра в системе координат SceneKit, и это будет просто правильный размер. Если вы хотите, однако, вы можете экспериментировать с различными размерами сфер.

Следующая строка кода меняет геометрическую сетку типа SCNSphere на реальный объект — что-то, что мы можем изменить и сделать с другими вещами. В любом случае, SCNNode будет тем, что мы вернем к вызову функции.

Наконец, беря параметр position из функции, мы просто размещаем узел, в который он должен быть помещен, на основе касания (которое мы еще не создали).

Эта часть действительно не нужна, но всегда хорошо, чтобы ваше приложение выглядело красиво, а также, это поможет вам узнать об освещении этих искусственных объектов для будущих приложений.

Начните с создания пустого материала:

1
2
// Creates a material that is recognized by SceneKit
let material = SCNMaterial()

Здесь мы просто говорим SceneKit, что появится новый материал, к которому мы добавим свойства позже. Другими словами, мы просто создали экземпляр SCNMaterial() и присвоили его константе, называемой material .

Затем установите оранжевый цвет материала, выполнив это:

1
2
// Converts the contents of the PNG file into the material
material.diffuse.contents = UIColor.orange

Поскольку у нас нет изображения для обтекания сферы, установите его цвет на оранжевый. Да, просто оранжевый цвет. Однако, если бы вы использовали изображение, вам нужно было бы сделать то же самое, но вместо этого вместо него установите для material.diffuse.contents изображение.

Наконец, установите конфигурацию освещения и добавьте материал к сфере следующим образом:

1
2
3
4
5
// Creates realistic shadows around the sphere
material.lightingModel = .blinn
 
// Wraps the newly made material around the sphere
sphere.firstMaterial = material

Теперь мы увидим, как мы меняем то, как источники света в окружающей среде влияют на материал, который мы создали. Установив модель на модель .blinn , мы рассчитываем наши основные моменты, используя .blinn -Фонга . Нам не нужно сейчас вдаваться в детали, но эта конкретная модель освещения подойдет лучше всего для наших целей. Наконец, мы заменяем текущий материал сферы тем, который мы только что создали.

Если вам интересна модель освещения, которую мы только что использовали, вот что говорится в документации Apple о .blinn освещения .blinn :

Затенение, которое включает в себя свойства окружения, рассеянности и зеркальности, где зеркальные блики рассчитываются по формуле Блинна-Фонга (документация Apple)

Наконец, после создания сферы наш последний шаг — просто вернуть типизированную сферу SCNNode на сайт вызова функции. Просто вставьте эту строку прямо перед конечной фигурной скобкой вашей функции:

1
return node

Все сделано! Этот метод предназначен для создания сфер, а затем возвращает их. Помните, однако, что сферы не появятся, если вы на самом деле не вызовете метод, а затем добавите их в суперпредставление.

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

Мы уже многого достигли: мы создали приложение ARKit и создали основные элементы интерфейса для нашего инструмента измерения расстояния. Завтра мы закончим, позволив пользователям размещать эти сферы в точках реального мира, а затем вычислять расстояние между ними.

И пока вы здесь, посмотрите наш видеокурс по программированию ARKit для iOS . В этом курсе вы узнаете, как кодировать приложение ARKit от начала до конца!