Отображение файла dae с помощью ARKit и отслеживание якоря в сцене

Я пытаюсь ARKit, и я настроил ARSCNView, используя этот учебник.

Затем настройте отслеживание горизонтальных трехмерных плоскостей со второй частью этот учебник.

Я создал одно приложение для просмотра, а затем привязал ARSCNView к корневому представлению с выходом к моему ViewController.

Вот код в ViewController:

import UIKit
import ARKit

class ViewController: UIViewController {

    //MARK: Properties
    @IBOutlet weak var arScene: ARSCNView!

    //MARK: ARKit variables
    var realityConfiguration: ARWorldTrackingSessionConfiguration?

    //MARK: Lifecycle
    override func viewDidLoad() {
        super.viewDidLoad()

    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        self.prepare()
    }

    //MARK: Actions


    //MARK: Overrides
}

extension ViewController {
    func prepare() {
        //Check to see if active reality is supported
        guard ARSessionConfiguration.isSupported else {
            //Custom alert function that just quickly displays a UIAlertController
            AppDelegate.alert(title: "Not Supported", message: "Active Reality is not supported on this device")
            return
        }
        //Set up the ARSessionConfiguration
        self.realityConfiguration = ARWorldTrackingSessionConfiguration()
        //Set up the ARSCNView
        guard let config = self.realityConfiguration else {
            return
        }
        //Run the ARSCNView and set its delegate
        self.arScene.session.run(config)
        self.arScene.delegate = self
    }
}

extension ViewController: ARSCNViewDelegate {
    func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
        return nil
    }

    func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
        guard let planAnchor = anchor as? ARPlaneAnchor else {
            return
        }

        let plane = SCNPlane(width: CGFloat(planAnchor.extent.x), height: CGFloat(planAnchor.extent.z))
        let planeNode = SCNNode(geometry: plane)
        planeNode.position = SCNVector3Make(planAnchor.center.x, 0, planAnchor.center.z)

        planeNode.transform = SCNMatrix4MakeRotation(-Float.pi / 2, 1, 0, 0)

        node.addChildNode(planeNode)

    }

    func renderer(_ renderer: SCNSceneRenderer, willUpdate node: SCNNode, for anchor: ARAnchor) {
        print("Will updated Node on Anchor: \(anchor.identifier)")
    }

    func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
        print("Did updated Node on Anchor: \(anchor.identifier)")
    }

    func renderer(_ renderer: SCNSceneRenderer, didRemove node: SCNNode, for anchor: ARAnchor) {
        print("Removed Node on Anchor: \(anchor.identifier)")
    }
}

Я загрузил Xcode 9 бета-версию, следуя инструкциям Apple и понял, что мой телефон (iPhone 6) не имеет чипа A9, необходимого для объекта ARWorldTrackingSessionConfiguration.

Примерно наполовину в первом уроке, который я связал, Apple говорит, что вы все равно можете создавать AR-события без чипа A9. Однако они не вдаются в подробности. Кто-нибудь еще нашел отправную точку и готов предоставить пример кода использования файла .dae и

  • Выбор точки привязки для его отображения
  • Отслеживание, что узловая точка
  • Фактически отображение файла .dae

Ответ 1

На самом деле нет ничего, что могло бы увидеть ваш код - просто просмотр в реальном времени.

Основная причина, по которой вы не видите каких-либо дополнений в своей реальности, заключается в том, что ваш код добавляет содержимое SceneKit в сцену только тогда, когда привязки добавляются в ARSession... но вы не добавляете вручную никаких якорей и вы не включили определение плоскости, поэтому ARKit не добавляет автоматически привязки. Если вы включите обнаружение самолета, вы начнете куда-то...

self.realityConfiguration = ARWorldTrackingSessionConfiguration()
realityConfiguration?.planeDetection = .horizontal

Но вы все равно ничего не увидите. Это потому, что ваша реализация ARSCNViewDelegate имеет противоречивые инструкции. Эта часть:

func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
    return nil
}

... означает, что для ваших якорей не создаются узлы SceneKit. Поскольку нет узлов, ваша функция renderer(_:didAdd:for:) никогда не вызывается, поэтому ваш код внутри этого метода никогда не создает никакого содержимого SceneKit.

Если вы включите обнаружение плоскости и удалите/закомментируете метод renderer(_: nodeFor:), остальная часть вашего кода должна получить вам что-то вроде этого:

(Чистая белая область - это ваш SCNPlane. Мне пришлось развернуть свою крышку iPad на белом столе, чтобы получить достаточно деталей сцены для обнаружения самолета, чтобы найти что-нибудь. Также проверьте фон... на самом деле был момент на WWDC сегодня, где торговый магазин не был заполнен людьми.)

Что касается того, нужен ли вам A9, обмен сообщениями Apple здесь немного неясен. Когда они говорят, что ARKit требует A9 или лучше, то, что они на самом деле означают, это ARWorldTrackingSessionConfiguration. И это там, где есть лучшая магия AR. (Там даже UIRequiredDeviceCapabilities ключ для arkit, который на самом деле охватывает устройства с поддержкой мирового отслеживания, поэтому вы можете ограничить свое приложение в App Store предлагаемыми только для этих устройств.)

Однако все еще есть ARKit без отслеживания мира. Запустите сеанс с базовым классом ARSessionConfiguration, и вы получите отслеживание только ориентации. (Отсутствие отслеживания местоположения, определение плоскости, отсутствие тестирования на удар).

Что это значит? Ну, если вы играли в текущую версию Pokémon GO, она работает так: потому что она отслеживает только ориентацию устройства, а не позицию, вы не можете приблизиться к Пикачу или прогуляться позади него - иллюзия, что он занимает реальную мир держится, пока вы только наклоняете или поворачиваете свое устройство, не перемещая его.

Вы загружаете 3D-контент с помощью SceneKit и размещаете его в AR так же, как вы загружаете и размещаете его в любом другом приложении/игре SceneKit. Для этого есть много ресурсов и множество способов сделать это. Один из них вы найдете в шаблоне Xcode при создании нового проекта AR и выберите SceneKit. Загрузочная часть выглядит примерно так:

let scene = SCNScene(named: "ship.scn" inDirectory: "assets.scnassets")
let ship = scene.rootNode.childNode(withName: "ship", recursively: true)

Затем поместите его:

ship.simdPosition = float3(0, 0, -0.5) 
// half a meter in front of the *initial* camera position
myARSCNView.scene.rootNode.addChildNode(ship)

Основное отличие, которое следует помнить для размещения вещей в AR, состоит в том, что позиции измеряются в метрах (и ваш контент должен быть спроектирован так, чтобы он был разумно измерен в метрах).