【ARKit】平面を検出して球体を出現させる

Blog Single

みなさん、こんにちは。

最近寒くて、朝なかなか布団から出られません、渋谷です。

今回はARKitを使って平面を検知し、その上に白い球体を出現させてみようと思います。

■完成イメージ

ARKitとは

ARKitとはAppleが提供しているiOS端末で簡単にARコンテンツを作成できるフレームワークのことです。今秋にARKit2がリリースされたばかりで、Xcodeから簡単に利用する事ができます。

公式:ARKit

プロジェクトの作成

Xcodeを開いたらCreate a new Xcode projectを選択し、

Augmented Reality Appを選択します。

項目を適当に入力し、プロジェクトの保存場所を選んだら準備完了です。

正常に準備されているか確認しましょう。
実機を接続し、左上のBuildボタンで実機にインストールします。
起動して、飛行機が表示されていれば大丈夫です。

実装

ViewController.swiftに書き加えて行きます。

    override func viewDidLoad() {
        super.viewDidLoad()

        // Set the view's delegate
        sceneView.delegate = self

        // Show statistics such as fps and timing information
        sceneView.showsStatistics = true

        // Create a new scene
        // コメントアウト
        // let scene = SCNScene(named: "art.scnassets/ship.scn")!

        // Set the scene to the view
        // コメントアウト
        // sceneView.scene = scene

        // 新しいシーンを作成
        sceneView.scene = SCNScene()

        // 特徴点を表示
        sceneView.debugOptions = [ARSCNDebugOptions.showFeaturePoints]

        // ライト追加
        sceneView.autoenablesDefaultLighting = true;
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        // Create a session configuration
        let configuration = ARWorldTrackingConfiguration()

        // 平面検出
        configuration.planeDetection = .horizontal

        // Run the view's session
        sceneView.session.run(configuration)
    }

    // 平面を検出したときに呼ばれる
    func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
        // 球のノードを作成
        let sphereNode = SCNNode()
        // ノードにGeometryとTransformを設定
        sphereNode.geometry = SCNSphere(radius: 0.05)
        // 検出面の子要素にする
        sphereNode.position.y += Float(0.05)
        node.addChildNode(sphereNode)
    }

以上です!!
Buildして確認すると、カメラで平面を検出して球体が出現するのが分かるかと思います。

解説

■特徴点を表示

特異点を表示としてdebugOptionsshowFeaturePointsを設定しています。これにより、画面上の色の変化や明るさ、輪郭から特徴点を検出してそれを黄色い点として表示しています。
debugOptionsにはshowWorldOriginも設定可能です。これはアプリが起動した時の中心部分と向きをx軸、y軸、z軸で表示してくれます。

■ライト追加

これとても大事です!!
sceneView.autoenablesDefaultLightingtrueにすることでライトを追加することができます。これをしないと、単色で立体感のない表示になってしまいます。

■ライトがない時

■平面検出

ARWorldTrackingConfigurationplaneDetection.horizontalを設定するこで、平面の検出ができるようになります。また、.horizontalではなく.verticalを設定すると垂直面の検出ができるようになります。両方を検出したい場合は下記のようにしましょう。

configuration.planeDetection = [.horizontal, .vertical]

■renderer(renderer: didAdd: anchor:)

ARKitで平面が検知されるとrenderer(renderer: didAdd: anchor:)メソッドが自動的に呼び出されます。 今回は平面を検出してその上に球体を出現させる事が目的なので、この中に球体の出現と作成の処理を書いています。
検出された平面の情報は引数(nodeとanchor)に格納されており、nodeは平面のNodeが持つ情報、anchorは座標と方向をそれぞれ持っています。

まとめ

プロジェクト作成時に自動で生成されるコードから大きく変化させずにここまで作れるなんてとても手軽ですね!
ARWorldTrackingConfigurationの設定にはplaneDetectionの他にもdetectionImagesdetectionObjectsなどがあるので、今度試してみたいと思います。

Posted by ShibuyaYuuki
今はPHPで開発を行なっているエンジニア。 就職してから体重が15キロ増えました!!

Other Posts: