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

みなさん、こんにちは。
最近寒くて、朝なかなか布団から出られません、渋谷です。
今回は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して確認すると、カメラで平面を検出して球体が出現するのが分かるかと思います。
解説
■特徴点を表示
特異点を表示
としてdebugOptions
にshowFeaturePoints
を設定しています。これにより、画面上の色の変化や明るさ、輪郭から特徴点を検出してそれを黄色い点として表示しています。
debugOptions
にはshowWorldOrigin
も設定可能です。これはアプリが起動した時の中心部分と向きをx軸、y軸、z軸で表示してくれます。
■ライト追加
これとても大事です!!
sceneView.autoenablesDefaultLighting
をtrue
にすることでライトを追加することができます。これをしないと、単色で立体感のない表示になってしまいます。
■ライトがない時
■平面検出
ARWorldTrackingConfiguration
のplaneDetection
に.horizontal
を設定するこで、平面の検出ができるようになります。また、.horizontal
ではなく.vertical
を設定すると垂直面の検出ができるようになります。両方を検出したい場合は下記のようにしましょう。
configuration.planeDetection = [.horizontal, .vertical]
■renderer(renderer: didAdd: anchor:)
ARKitで平面が検知されるとrenderer(renderer: didAdd: anchor:)
メソッドが自動的に呼び出されます。 今回は平面を検出してその上に球体を出現させる事が目的なので、この中に球体の出現と作成の処理を書いています。
検出された平面の情報は引数(nodeとanchor)に格納されており、nodeは平面のNodeが持つ情報、anchorは座標と方向をそれぞれ持っています。
まとめ
プロジェクト作成時に自動で生成されるコードから大きく変化させずにここまで作れるなんてとても手軽ですね!
ARWorldTrackingConfiguration
の設定にはplaneDetection
の他にもdetectionImages
やdetectionObjects
などがあるので、今度試してみたいと思います。