web-dev-qa-db-ja.com

ARKitを使用してDAEファイルを表示し、シーン内のアンカーを追跡する

ARKitを試してみて、 このチュートリアル を使用してARSCNViewを設定しました。

次に このチュートリアル。 の2番目の部分で水平3D平面の追跡を設定します。

単一のビューアプリケーションを作成し、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にARWorldTrackingSessionConfigurationオブジェクトに必要なA9チップがないことに気付きました。

私がリンクした最初のチュートリアルの半分ほど、Appleは、A9チップがなくてもARエクスペリエンスを作成できると言っています。ただし、詳細については触れていません。他の誰かが出発点を見つけましたか、そして、.daeファイルを使用するコード例を提供することをいとわない

  • アンカーポイントを選択して表示する
  • そのアンカーポイントの追跡
  • 実際に.daeファイルを表示する
12
Jon Vogel

コードを使用して確認するものは何もありません。ライブカメラビューだけです。

現実に拡張機能が表示されない主な理由は、アンカーがARSession...に追加されたときにのみコードがSceneKitコンテンツをシーンに追加するが、手動でアンカーを追加していないためです。平面検出を有効にしていないため、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マジックです。 (UIRequiredDeviceCapabilitiesarkitキーでさえ、実際に世界の追跡をサポートするデバイスをカバーしているため、App Storeのアプリをそれらのデバイスのみに提供されるように制限できます。)

ただし、ワールドトラッキングのないARKitはまだいくつかあります。基本クラス ARSessionConfiguration でセッションを実行すると、方向のみの追跡が行われます。 (位置追跡なし、平面検出なし、ヒットテストなし)

それで何ができるの?さて、あなたがポケモンGOの現在のバージョンをプレイした場合、それはそのように機能します:位置ではなくデバイスの向きのみを追跡するため、ピカチュウに近づいたり、後ろを歩き回ったりすることはできません。あなたがそれを動かさずにあなたのデバイスを傾けるか、または回すだけである限り、世界は保持します。

SceneKitを使用して3Dコンテンツをロードし、それを他のSceneKitアプリ/ゲームにロードして配置するのと同じようにARに配置します。このためのリソースはたくさんあり、それを行う方法はたくさんあります。それらの1つは、新しいARプロジェクトを作成してSceneKitを選択したときにXcodeテンプレートにあります。読み込み部分は次のようになります。

_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に配置する際に覚えておくべき主な違いは、位置はメートル単位で測定されることです(コンテンツはメートル単位で適切にサイズ設定されるようにコンテンツを設計する必要があります)。

31
rickster