スタッフブログ

STAFF BLOG

アプリ開発日誌

2018.03.07

【Swift】初心者でも簡単にできるARKitを使ってみよう(2)

こんにちは、松田翔大です。

前回(初心者でも簡単にできるARKitを使ってみよう)最後に書いた通り、カメラで平面を検知して、そこに3Dモデルを表示させるところまでやってみたので書いてみました。

#事前準備

まずは前回同様、Xcodeでプロジェクトを作成します。

Xcodeの環境も前回と同様です。

まず、新規のファイルを作成します。今回は、PlaneNode.swiftファイルを作成します。

作成する方法は、作成したプロジェクトのプロジェクト名のフォルダを右クリック -> New File… -> Cocoa Touch Classを選択してNextを押す。

スクリーンショット 2018-02-28 13.08.59

Class:に[PlaneNode]と入力し、Subclass of:はNSObjectを選択し、Nextを押します。

スクリーンショット 2018-02-28 13.07.16

この画面はそのままCreateを押せば問題ないです。

スクリーンショット 2018-02-28 13.09.31

これでPlaneNode.swiftが作成されます。
スクリーンショット 2018-02-28 13.12.00

#実装

まずは、先程作成したPlaneNode.swiftを実装していきます。

以下のように実装してください。

PlaneNode.swift

import UIKit
import SceneKit
import ARKit

class PlaneNode: SCNNode {
    
    fileprivate override init() {
        super.init()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    init(anchor: ARPlaneAnchor) {
        super.init()
        // ARAnchorの情報に基づいて、半透明の平面を表現するノードオブジェクトの作成
        geometry = SCNPlane(width: CGFloat(anchor.extent.x), height: CGFloat(anchor.extent.z))
        let planeMaterial = SCNMaterial()
        planeMaterial.diffuse.contents = UIColor.white.withAlphaComponent(0.5)
        geometry?.materials = [planeMaterial]
        SCNVector3Make(anchor.center.x, 0, anchor.center.z)
        transform = SCNMatrix4MakeRotation(-Float.pi / 2, 1, 0, 0)
    }
    
    func update(anchor: ARPlaneAnchor) {
        (geometry as! SCNPlane).width = CGFloat(anchor.extent.x)
        (geometry as! SCNPlane).height = CGFloat(anchor.extent.z)
        position = SCNVector3Make(anchor.center.x, 0, anchor.center.z)
    }
}

次にViewController.swiftを実装します。

以下のように実装してください。

ViewController.swift

import UIKit
import SceneKit
import ARKit

class ViewController: UIViewController, ARSCNViewDelegate {

    @IBOutlet var sceneView: ARSCNView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        sceneView.delegate = self
        sceneView.scene = SCNScene()
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        let configuration = ARWorldTrackingConfiguration()
        // 平面の検出を有効化する
        configuration.planeDetection = .horizontal
        sceneView.session.run(configuration)
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        
        sceneView.session.pause()
    }
    
    // MARK: - ARSCNViewDelegate
    // ARPlaneAnchorが検出されて、自動的にシーンに追加される時に呼ばれる
    func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
        DispatchQueue.main.async {
            if let planeAnchor = anchor as? ARPlaneAnchor {
                // 平面を表現するノードを追加する
                node.addChildNode(PlaneNode(anchor: planeAnchor) )
            }
        }
    }
    
    // 情報が更新されるたびにARPlaneAnchorも更新されて呼ばれる
    func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
        DispatchQueue.main.async {
            if let planeAnchor = anchor as? ARPlaneAnchor, let planeNode = node.childNodes[0] as? PlaneNode {
                // ノードの位置及び形状を修正する
                planeNode.update(anchor: planeAnchor)
            }
        }
    }
}

これで実装は終わりです。
ビルドして確認して以下の画像のようになっていれば問題ありません。
Image uploaded from iOS

今回は、ARKitで平面を検出するところまでで終わりたいと思います。
次回は、今回書ききれなかった検出した平面に3Dオブジェクトを設置するところまで書きたいと思います。

BACK

お問合せ

イーディーエーに興味をお持ちいただいて
ありがとうございます!
スマホアプリに関するご相談、
お見積りや弊社へのご質問など、
お気軽にお問い合わせください。
担当者より折り返しご連絡させていただきます。

    お名前必須
    会社名
    メールアドレス必須
    電話番号必須
    お問合わせ種別必須
    お問合わせ内容必須

    アンケートにご協力ください。
    弊社サイトへはどのようにしてアクセスされましたか?

    個人情報のお取扱いに関する同意事項

    1.事業者の氏名又は名称

    株式会社イーディーエー

    2.個人情報保護管理者の氏名又は職名、所属及び連絡先

    個人情報保護管理者 小宮 保人
    Mail:[email protected]

    3.取得した個人情報の利用目的

    当フォームで取得した個人情報は、お問い合わせに関する回答のために利用し、目的外利用はいたしません。

    4.弊社が取得した個人情報の第三者への委託、提供について

    弊社は、ご本人に関する情報をご本人の同意なしに第三者に委託または提供することはありません。

    5.個人情報保護のための安全管理

    弊社は、ご本人の個人情報を保護するための規程類を定め、従業者全員に周知・徹底と啓発・教育を図るとともに、その遵守状況の監査を定期的に実施いたします。
    また、ご本人の個人情報を保護するために必要な安全管理措置の維持・向上に努めてまいります。

    6.個人情報の開示・訂正・利用停止等の手続

    ご本人が、弊社が保有するご自身の個人情報の、利用目的の通知、開示、内容の訂正、追加又は削除、利用の停止、消去及び第三者への提供の停止を求める場合には、下記に連絡を頂くことで、対応致します。

    株式会社イーディーエー 個人情報お問合せ窓口
    〒106-0032 東京都港区六本木7丁目14番23 ラウンドクロス六本木4F
    TEL:03-5422-7524 FAX:03-5422-7534
    Mail:[email protected]

    7.ご提供いただく情報の任意性

    個人情報のご提供は任意ですが、同意を頂けない場合には、第3項にあります利用目的が達成できない事をご了承いただくこととなります。

    8.弊社Webサイトの運営について

    弊社サイトでは、ご本人が弊社Webサイトを再度訪問されたときなどに、より便利に閲覧して頂けるよう「クッキー(Cookie)」という技術を使用することがあります。これは、ご本人のコンピュータが弊社Webサイトのどのページに訪れたかを記録しますが、ご本人が弊社Webサイトにおいてご自身の個人情報を入力されない限りご本人ご自身を特定、識別することはできません。
    クッキーの使用を希望されない場合は、ご本人のブラウザの設定を変更することにより、クッキーの使用を拒否することができます。その場合、一部または全部のサービスがご利用できなくなることがあります。