#この記事について
前回の記事( 今日からはじめる AR プログラミング Part.1)では、
ARKit を使ったシンプルなアプリケーションを開発して、どのように空間トラッキングをしているかを体験した。
今回は、もう少しだけ ARKit の機能を使ってみる。
#どんな人のための記事?
- Xcode の基本的な使い方を理解している。
- Swift プログラミングの基本を理解している。
- AR (Augmented Reality) に興味がある。
#要件
- Xcode9 以降が動作する Mac
- A9 プロセッサを搭載している iOS デバイス(iOS11~)
#開発するアプリケーションの概要
- AR 空間に、3D コンテンツの画像を配置する。
- タッチジェスチャー
- SceneKit
#ARKit と SceneKit
AR は「拡張された現実」のこと。
今回の記事では、現実空間を仮想の 3D コンテンツで拡張してみる。
iOS プログラミングで、3D コンテンツを扱う時に便利なフレームワークが SceneKit
。
SceneKit の仮想空間では「x,y,z」の3軸、つまり「水平、垂直、奥行き」の座標系で位置情報を扱う。
#手順
##1. Xcode プロジェクトを作成
####プロジェクトの設定
####Info.plist
##2. ユーザーインターフェース
####iPhoneX 向けのデザイン
オートレイアウト
####タップを検知する
UITapGestureRecognizer を配置する
####IBOutlet 接続
arScnView
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var arScnView: ARSCNView!
override func viewDidLoad() {
super.viewDidLoad()
}
}
####IBAction 接続
handleTap メソッド
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var arScnView: ARSCNView!
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func handleTap(_ sender: UITapGestureRecognizer) {
}
}
##3. ソースコード
####フレームワークをインポートする
今回は ARKit に加えて、3D オブジェクトを生成・配置するために SceneKit フレームワークを使用する。
import ARKit
import SceneKit
class ViewController: UIViewController {
@IBOutlet weak var arScnView: ARSCNView!
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func handleTap(_ sender: UITapGestureRecognizer) {
}
}
####セッションとコンフィギュレーション
前回とほぼ同じ内容。ただし、今回はデバッグ情報は表示しない。
import ARKit
import SceneKit
class ViewController: UIViewController {
@IBOutlet weak var arScnView: ARSCNView!
override func viewDidLoad() {
super.viewDidLoad()
let scene = SCNScene()
arScnView.scene = scene
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let configuration = ARWorldTrackingConfiguration()
arScnView.session.run(configuration)
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
arScnView.session.pause()
}
@IBAction func handleTap(_ sender: UITapGestureRecognizer) {
}
}
####完成したソースコード
import ARKit
import SceneKit
class ViewController: UIViewController {
@IBOutlet weak var arScnView: ARSCNView!
override func viewDidLoad() {
super.viewDidLoad()
let scene = SCNScene()
arScnView.scene = scene
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let configuration = ARWorldTrackingConfiguration()
arScnView.session.run(configuration)
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
arScnView.session.pause()
}
@IBAction func handleTap(_ sender: UITapGestureRecognizer) {
guard let currentFrame = arScnView.session.currentFrame else { return }
let viewWidth = arScnView.bounds.width
let viewHeight = arScnView.bounds.height
let imagePlane = SCNPlane(width: viewWidth/6000, height: viewHeight/6000)
imagePlane.firstMaterial?.diffuse.contents = arScnView.snapshot()
imagePlane.firstMaterial?.lightingModel = .constant
let planeNode = SCNNode(geometry: imagePlane)
arScnView.scene.rootNode.addChildNode(planeNode)
var translation = matrix_identity_float4x4
translation.columns.3.z = -0.1
planeNode.simdTransform = matrix_multiply(currentFrame.camera.transform, translation)
}
}
##4. ビルド
アプリが起動したら、画面をタップしてみる。
タップした瞬間にデバイス画面に映っていた画像が AR 空間に配置されれば、アプリケーションは正しく動作している。