ARKit入門 / タップ位置へのモデル配置
iOSの「ARKit」でタップ位置のモデル配置を行うプログラムを作ります。
1. モデルの追加
プロジェクトの「art.scnassets」にモデルを追加します。テクスチャなどを設定した後、メニュー「Editor → Convert to SeaneKit scene file format(.scn)」でscnに変換します。
2. タップ位置へのモデル配置
検出した平面のタッチ位置にモデル配置を行います。
import UIKit
import SceneKit
import ARKit
//タップ位置へのモデル配置
class ViewController: UIViewController, ARSCNViewDelegate {
@IBOutlet var sceneView: ARSCNView!
//ロード時に呼ばれる
override func viewDidLoad() {
super.viewDidLoad()
//シーンの作成
sceneView.scene = SCNScene()
//特徴点とワールド原点の表示
sceneView.debugOptions = [
ARSCNDebugOptions.showFeaturePoints,
ARSCNDebugOptions.showWorldOrigin]
//光源の有効化
sceneView.autoenablesDefaultLighting = true;
//ARSCNViewデリゲートの指定
sceneView.delegate = self
//ジェスチャーの追加
let gesture = UITapGestureRecognizer(target: self, action:#selector(onTap))
self.sceneView.addGestureRecognizer(gesture)
}
//ビュー表示時に呼ばれる
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()
}
//ARアンカー追加時に呼ばれる
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
DispatchQueue.main.async {
//ARAnchorのnameがmodelの時
if anchor.name == "model" {
//モデルノードの追加
let scene = SCNScene(named: "art.scnassets/heniheni.scn")
let modelNode = (scene?.rootNode.childNode(withName: "heniheni", recursively: false))!
modelNode.scale = SCNVector3(0.001, 0.001, 0.001)
node.addChildNode(modelNode)
}
}
}
//タップ時に呼ばれる
@objc func onTap(sender: UITapGestureRecognizer) {
//タップ位置の取得
let location = sender.location(in: sceneView)
//ヒットテスト
let hitTest = sceneView.hitTest(location, types: .existingPlaneUsingExtent)
if !hitTest.isEmpty {
//ARアンカーの追加
let anchor = ARAnchor(name:"model", transform: hitTest.first!.worldTransform)
sceneView.session.add(anchor: anchor)
}
}
}
◎ジェスチャーの追加
ジェスチャーの追加には、UITapGestureRecognizerを生成し、addGestureRecognizer()で追加します。
//ジェスチャーの追加
let gesture = UITapGestureRecognizer(target: self, action:#selector(onTap))
self.sceneView.addGestureRecognizer(gesture)
◎ヒットテスト
ヒットテストには、ARSCNViewのhitTest()を使います。
func hitTest(_ point: CGPoint, types: ARHitTestResult.ResultType) -> [ARHitTestResult]
SceneKitViewのポイントに対応するカメラ映像で、実世界のオブジェクトまたはARアンカーを検索
point: ポイント
types: 種別
.featurePoint: 特徴点
.estimatedHorizontalPlane: 水平面
.existingPlane: 平面
.existingPlaneUsingExtent: 平面内
戻り値: ヒットテスト結果
ヒットテストで衝突検出時に、ARアンカーの生成と追加を行います。
◎モデルノードの追加
ARAnchorのnameが"model"の時、モデルノードを追加します。
//ARAnchorのnameがmodelの時
else if anchor.name == "model" {
//モデルノードの追加
let scene = SCNScene(named: "art.scnassets/heniheni.scn")
let modelNode = (scene?.rootNode.childNode(withName: "heniheni", recursively: false))!
modelNode.scale = SCNVector3(0.001, 0.001, 0.001)
node.addChildNode(modelNode)
}
この記事が気に入ったらサポートをしてみませんか?