今年のWWDCの基調講演は、エンドユーザ向けの新機能の話に終止した感が強く、デベロッパ的にはあまりピンと来ない2時間だったように思います。が、State of the Unionやドキュメントを見ると、試してみたい新APIが目白押しです。例年通り、気になったものを列挙していきます 1。
全部書いてると時間かかりそうなので、まずは本記事では ARKit 2 について。
Multiuser and Persistent AR
自分が見ているARの世界を共有・永続化できるようになったというのは本当に大きいです。Appleのデモは「ゲームで対決できます」みたいな派手なものでしたが、たとえば奥さんの机に花を置いておくとかみたいなささやかなものでもいいですし、ソーシャルコミュニケーションな何かでもいいですし、教育的な何かでも使えそうですし、とにかく「自分しか見れない」という従来の制約がなくなるだけでARを利用したアプリのアイデアはめちゃくちゃ広がると思います。
API的には、ARWorldMap
というクラスが追加されていて、これが「世界」の情報で、これを保存したりシェアしたりするようです。
ARMultiuserというサンプルが公開されていて、送受信のあたりのコードはこんな感じです。
(送る側)
sceneView.session.getCurrentWorldMap { worldMap, error in guard let map = worldMap else { print("Error: \(error!.localizedDescription)"); return } guard let data = try? NSKeyedArchiver.archivedData(withRootObject: map, requiringSecureCoding: true) else { fatalError("can't encode map") } self.multipeerSession.sendToAllPeers(data) }
(受け取り側)
if let unarchived = try? NSKeyedUnarchiver.unarchivedObject(of: ARWorldMap.classForKeyedUnarchiver(), from: data), let worldMap = unarchived as? ARWorldMap { // Run the session with the received world map. let configuration = ARWorldTrackingConfiguration() configuration.planeDetection = .horizontal configuration.initialWorldMap = worldMap sceneView.session.run(configuration, options: [.resetTracking, .removeExistingAnchors]) // Remember who provided the map for showing UI feedback. mapProvider = peer }
ここで面白いのは、このサンプルでは送受信に Multipeer Connectivity を使っていて、データとしては普通にNSKeyedArchiver
でアーカイブ/アンアーカイブしたデータを送り合っている点です。
つまり、送受信や保存の方法はARKitに依存しておらず、なんでもOKということです。データをサーバに送ってもいいわけですが、バックエンドを用意せずとも、サクッとUserDefaults
に保存してもいいし、Realm
に保存してもいいし、Core Bluetooth(BLE)を利用しても良いわけです。([PR]その際、こういう本が役に立つかもしれません)
3D Object Detection
「3D物体検出」は従来の(2D)物体検出と何が違うかというと、「正面から見た状態」だけでなく、横からでも、後ろからでも、上からでも、その物体を認識できるということです。この機能により、現実空間の物体(銅像とか)をマーカーとして仮想コンテンツを置く、といったことが可能になります。
ARKit 2には、3D物体を「スキャン」して「リファレンスオブジェクト」を生成する機能と、そのリファレンスオブジェクトと同じ特徴を持つ物体を現実空間から検出する機能とが追加されています。
(サンプルに同梱されている画像。スキャン〜検出の流れが示されている)
このわりと複雑なスキャンフロー、出来合いのやつがあるのかなと思いきや、ソースを見てみるとがっつりアプリ側で実装されています。3Dバウンディングボックスを順番に埋めていくのとかも全部。まぁ、ここはUIUXとして工夫のしがいがあるところなので、この方が良いですよね。
スキャンする際は、コンフィギュレーションとしてARObjectScanningConfiguration
を使用します。
let configuration = ARObjectScanningConfiguration()
で、スキャン中にどういうことをするかですが・・・非常に泥臭い実装がされています。ここでは省略しますが、ARSessionDelegate
の各デリゲートメソッドから実装を追ってみてください。
リファレンスオブジェクトを表すARReferenceObject
を作成するには、ARSession
のcreateReferenceObject(transform:center:extent:completionHandler:)
メソッドを呼びます。この引数に、スキャン対象のバウンディングボックスのtransform, center, extentを渡します。
sceneView.session.createReferenceObject( transform: boundingBox.simdWorldTransform, center: float3(), extent: boundingBox.extent, completionHandler: { object, error in if let referenceObject = object { // Adjust the object's origin with the user-provided transform. ... } else { print("Error: Failed to create reference object. \(error!.localizedDescription)") ... } })
ARKitの新規追加API
新APIを眺めるだけでもいろいろと察することはできるので、ざーっと載せておきます。
- ARWorldMap
The space-mapping state and set of anchors from a world-tracking AR session.
- AREnvironmentProbeAnchor
An object that provides environmental lighting information for a specific area of space in a world-tracking AR session.
- ARReferenceObject
A 3D object to be recognized in the real-world environment during a world-tracking AR session.
- ARObjectAnchor
Information about the position and orientation of a real-world 3D object detected in a world-tracking AR session.
- ARObjectScanningConfiguration
A configuration that uses the back-facing camera to collect high-fidelity spatial data for use in scanning 3D objects for later detection.
ARFaceAnchor - 目の動きのトラッキング
var leftEyeTransform: simd_float4x4
A transform matrix indicating the position and orientation of the face's left eye.
var rightEyeTransform: simd_float4x4
A transform matrix indicating the position and orientation of the face's right eye.
var lookAtPoint: simd_float3
A position in face coordinate space estimating the direction of the face's gaze.
ARImageTrackingConfiguration
A configuration that uses the back-facing camera to detect and track known images.