LoginSignup
4
5

More than 5 years have passed since last update.

ARKit基礎まとめ - 平面検出して3Dオブジェクトを置く

Last updated at Posted at 2018-12-31

ARKit基礎

2018年もあと1時間で終了です。
今年は、ARのデモアプリをいくつか作ったりしましたが、AppStoreに出す程のアプリがまだ開発できていない事が心残りです。

来年こそ、ARKitを使いこなしていきたいと思っているのですが、UIKitほどまだ仲良くなれていない感じがするので、今更ながらARKitの基本的な使い方や作法をまとめて復習していきます。

平面検出して3Dオブジェクトを置く

デモで一番良くみる平面検出して、3Dオブジェクトを置くやつ。

最低限のコードで平面検出 + 3Dオブジェクト配置を実装するには以下の様な流れになります。

  • ARSCNViewの設定(水平面を検出する設定)
  • 3Dオブジェクト取り込み用のメソッドの準備(今回はdaeファイル)
  • ARSCNViewDelegateのメソッドで3Dオブジェクトを配置

ARSCNViewの設定

ViewController.swift
class ViewController: UIViewController {

    @IBOutlet var sceneView: ARSCNView!

    override func viewDidLoad() {
        super.viewDidLoad()

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

        // fps情報などを表示
        sceneView.showsStatistics = true

        // デバッグ用に特徴点を表示
        sceneView.debugOptions = ARSCNDebugOptions.showFeaturePoints

        //Viewに初期化したsceneをセット
        sceneView.scene = SCNScene()
    }

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

        // Sessionの設定
        let configuration = ARWorldTrackingConfiguration()

        // .horizontalで水平面 (.verticalだと垂直面を検知)
        configuration.planeDetection = .horizontal

        //空間から光の情報を取得し画面上のライトの情報に適応
        configuration.isLightEstimationEnabled = true

        // sessionをスタート
        sceneView.session.run(configuration)
    }

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

        // sessionをストップ
        sceneView.session.pause()
    }

3Dオブジェクト取り込み用のメソッド

dae形式のファイルを取り込み
こちらの3Dモデルを利用させていただきました。
Beer bottle

ViewController.swift
    func load3dObject() -> SCNNode {
        let url = Bundle.main.url(forResource: "3d.scnassets/bottle", withExtension: "dae")!
        let sceneSource = SCNSceneSource(url: url, options: nil)!
        let virtualObjectNode
            = sceneSource.entryWithIdentifier("bottle", withClass: SCNNode.self)!
        return virtualObjectNode
    }

ARSCNViewDelegateのメソッドで配置

平面を新たに検知した際に、呼ばれるrenderer(_:didAdd:for:)で、検知したNodeに3DオブジェクトのNodeを追加

ViewController.swift
    func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
        node.addChildNode(load3dObject())
    }

結果

シャドーやライトを調整しないとあまりリアリティが出ないですね。
あと、特徴量の少ない真っ白な床とかは、うまく検出できません。
アプリ化する際には、インストラクションをうまく作らないとユーザにストレスを与えてしまいそうです。

IMG_0486.PNG

4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5