今回の記事はARkitを用いてAR空間内に任意の3Dオブジェクトを配置する方法についてご紹介します。
完成イメージは下記のようになっております。
今回の記事の内容でscn形式のファイルを使用しますが、この形式を入手・作成す方法については下記の記事を書いておりますので気になる方はこちらのリンクからご参照ください。
私のステータスとしてはAR関連についてはかなりの初心者となっております。そのため初心者でもわかるようにできるだけ簡単な方法でお伝えできるように丁寧に解説を行うことを心がけます。
ではメインの記事に進んで行きます。
ARkitで3DオブジェクトをAR空間に配置する際のXcode設定
まずはXcodeのプロジェクトをいつものように作成していきます。
この辺りの操作に関してはなれてきましたね。
次に今回配置する3オブジェクトをXcodeの適当なassetフォルダに格納します。
finderから適当にスライドすればimportできるので簡単です。
daeファイルをscn形式の拡張子に変更しておくことを忘れずに。
方法は先ほどのリンクをご参照ください。
また、大体の3Dオブジェクトは非常に大きなサイズになっているのでscaleを小さめに設定しておけばいいと思います。大体0.02。下記のように3Dオブジェクトを選択して再度バーで調節してください。
identiferはファイル名と同名にしておけば管理しやすいです。
以上でXcode側の設定は終了です。次はコードに移ります。
ARkitで3DオブジェクトをAR空間に配置する際のSwiftコード
import UIKit
import SceneKit
import ARKit
class ViewController: UIViewController {
@IBOutlet var sceneView: ARSCNView!
let configuration = ARWorldTrackingConfiguration()
override func viewDidLoad() {
super.viewDidLoad()
initialize()
registerGestureRecognizers()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
/// ARSCNiew初期化設定
func initialize (){
self.sceneView.debugOptions = [ARSCNDebugOptions.showWorldOrigin,ARSCNDebugOptions.showFeaturePoints]
self.configuration.planeDetection = .horizontal
self.sceneView.session.run(configuration)
self.sceneView.autoenablesDefaultLighting = true
}
/// メインのビューのタップを検知するように設定する
func registerGestureRecognizers() {
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action:#selector(tapped))
self.sceneView.addGestureRecognizer(tapGestureRecognizer)
}
@objc func tapped(sender: UITapGestureRecognizer) {
// タップされた位置を取得する
let sceneView = sender.view as! ARSCNView
let tapLocation = sender.location(in: sceneView)
// タップされた位置のARアンカーを探す
let hitTest = sceneView.hitTest(tapLocation, types: .existingPlaneUsingExtent)
if !hitTest.isEmpty {
// タップした箇所が取得できていればitemを追加
self.addItem(hitTestResult: hitTest.first!)
}
}
/// アイテム配置メソッド
func addItem(hitTestResult: ARHitTestResult) {
// アセットのより、シーンを作成
let scene = SCNScene(named: "art.scnassets/eyeball.scn")
// ノード作成
let node = (scene?.rootNode.childNode(withName: "eyeball", recursively: false))!
// 現実世界の座標を取得
let transform = hitTestResult.worldTransform
let thirdColumn = transform.columns.3
// アイテムの配置
node.position = SCNVector3(thirdColumn.x, thirdColumn.y, thirdColumn.z)
self.sceneView.scene.rootNode.addChildNode(node)
}
}
上記が全体のコードです。
少しずつ解説を行っていきます。
func registerGestureRecognizers() {
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action:#selector(tapped))
self.sceneView.addGestureRecognizer(tapGestureRecognizer)
}
この部分がタップを検知してタップされればselectorでtapped関数を起動させる部分です。
@objc func tapped(sender: UITapGestureRecognizer) {
// タップされた位置を取得する
let sceneView = sender.view as! ARSCNView
let tapLocation = sender.location(in: sceneView)
// タップされた位置のARアンカーを探す
let hitTest = sceneView.hitTest(tapLocation, types: .existingPlaneUsingExtent)
if !hitTest.isEmpty {
// タップした箇所が取得できていればitemを追加
self.addItem(hitTestResult: hitTest.first!)
}
}
このtapped関数がAR空間内の位置情報とARアンカーを探して3DオブジェクトをaddItem関数で配置しているます。
以上でbuildすると下記のようにAR空間内の平面上に3Dオブジェクトを配置することができます。
コメント
[…] 今回の記事は以上ですが、3DオブジェクトをAR空間に配置する記事も今回の記事の内容を書いておりますので気になる方はこちらからご参照ください。 […]
[…] 「3Dオブジェクトを画面タップで表示させるSwiftコード」 […]