Apple Engine

Apple, iPhone, iOS, その周辺のことについて

iOS と macOS のアプリを統合すると噂の Project Marzipan について勝手な妄想

正直、現状から考えると当分先なきはするが勝手に妄想してみる。
多分、予想は間違っているけど。

 

現状の課題

macOS 10.4 からある PDFKit が iOS 11 から使えるようになったり、 iOS の Finder となりうる Files アプリが導入されたり、 SDK やシステムが iOS と macOS で似通ってきている。

ただ問題は UI が各 OS 異なっているものがあり、iOS と macOS で各UIに付随する機能やパーツを共有するのは難しいのではないかと思っている。
iOS で Array Controller などはないし、ボタン類だけでも多い。

もし行うのであれば、UI の共有化を地道に行うこととなるだろう。
それが完了してから tvOS のような形になるのではないかと思っていて、 数年でできる感じではないような気はしている。

 

統合プランその1

iOS のアプリを macOS でシミュレーションする

多分、これが一番想像しやすいパターン。 開発者向けの機能の Autolayout によって UI の配置や大きさがフレキシブルにできる(楽ではないが)ので、macOS 上で表示するだけなら問題ないと思われる。
また、iPad Pro の解像度は 2048 x 2732 なので、現状どの MacBook Pro 13 inch より解像度が高い。

iOS シミュレータで UI をマウスで使用する場合、使いづらい部分があるためこのようになるかは不明である。

もし、iOS アプリを実行するのであれば、実行専用の SoC チップを搭載する可能性もある。

 

統合プランその2

iOS のアプリのバイナリは同じで実行時に macOS の機能を呼び出す

Universal Windows Platform Bridge の Project Astoria の様に
macOS 上の iOS アプリ実行時に、macOS の機能と結びつけて実行する。

シュミレータを使用しないので速く起動しそうだが、Microsoft がこのシステムを諦めたのでまず難しいだろう。

 

統合プランその3

逆に iOS で macOS のアプリをシミュレーションして動かす

一番、夢がある。
A シリーズのチップが速くなってきたので iPad とかで macOS アプリが動いたら面白いかも。
もし、Xcode が iPad で動いたら胸熱ではある。

また、intel チップを使用せずに A シリーズのチップのみで構成 MacBook Pro などでても面白い。

 

ま、結果的にはこの場合は統合されてないんだけど・・・・・・。

 

統合プランその4

やっぱり地道にやる

NSColor や NSImage なんかの基本となる部分だけ、UIColor や UIImage などにして、 固有の UI や機能だけ別実装な感じで tvOS みたいな感じになるのだろう。

 

まとめ

とりあえず、実行が速くて開発が楽になればどの様な方法でも構わないし、iPad などで Xcode が使いたい。

それと、Swift、libswiftCore.dylib 的なやつをアプリに含めなくてもよくなる世界がおとずれて欲しい。

ARKit 1.5 で平面認識した箇所からポリゴンを描画する

ARKit 1.5 から平面を認識した箇所からポリゴンを描画し、 以前の ARKit ではできなかった丸いテーブルなど若干ではあるが形状に合わせた平面を描画できるようになった。 今回はその解説。

 

ひとまず注意点

  • Beta 版であるため今後仕様が変更される可能性がある
  • Beta 版の Xcode 9.3 使用するため iOS Developer Program 加入している必要がある
  • 端末カメラを使用するため iOS 11.5 をインストールした実機が必要がある
  • 今回は動作部分しか書かないのでエラー処理など追加する必要がある

 

下準備

画像認識の方にも書いたけどこちらにも同じものを書いておく。

 

その1:シーンファイルを消す

既存の Xcode 同様に New Project(Command+Shift+N)から「Augmented Reality App」を選択し、新しいプロジェクトを作成。

今回は AR ではテンプレートとしてつくられる Scene File を使用しないので ViewController.swift の27行目を変更

こちらから

let scene = SCNScene(named: "art.scnassets/ship.scn")!

こちらに変更

let scene = SCNScene()

 

Scene File は必要ないので art.scnassets も消してもらっても構わない。

 

その2:デバッグオプションで特徴点を描画する

この状態が表示しても現実世界のトラッキングか可能にになっているかわからないので、デバッグオプションで特徴点の表示を設定する。 以下のコードを先ほどの 「let scene = 〜」の上らへんに書く

sceneView.debugOptions = [ARSCNDebugOptions.showFeaturePoints]

実機にビルド後、トラッキングが可能になると特徴点が黄色い点として画面に描画される。

 

その3:ARWorldTrackingConfiguration の平面認識設定の追加

viewWillAppear にある「let configuration = ARWorldTrackingConfiguration()」の下に、 以下のものを書き、水平と垂直の平面を認識できるようにする。

configuration.planeDetection = [.vertical, .horizontal]

ひとまず準備完了。

 

平面認識部分のコード

今回の流れ

  • ARKit のデリゲート didUpdate でトラッキングが変更されるたび処理する命令を書く
  • DispatchQueue 内で処理をかく
  • ARPlaneAnchor からアンカーを取得
  • Metal のデフォルトデバイスを設定し ARSCNPlaneGeometry でジオメトリを初期化
  • アンカーから認識した領域のジオメトリ情報を取得し ARSCNPlaneGeometry の update に処理を渡す
  • 半透明のマテリアルを設定
  • 設置しているノードへ処理したジオメトリを渡し描画する

このぐらいでリアルタイムに平面の認識を描画できるようになるのでかなり簡単。

 

以下のコード「// MARK: - ARSCNViewDelegate」 の下あたりに書いてビルドすると完成

// ARKit のデリゲート didUpdate でトラッキングが変更されるたび処理する命令を書く
func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
    
    // DispatchQueue 内で処理をかく
    DispatchQueue.main.async {
        
        // ARPlaneAnchor からアンカーを取得したり平面のノードを調べる
        if let planeAnchor = anchor as? ARPlaneAnchor {
            // Metal のデフォルトデバイスを設定する
            let device: MTLDevice = MTLCreateSystemDefaultDevice()!
            // ARSCNPlaneGeometry でジオメトリを初期化
            let plane = ARSCNPlaneGeometry.init(device: device)
            // アンカーから認識した領域のジオメトリ情報を取得し ARSCNPlaneGeometry の update に処理を渡す
            plane?.update(from: planeAnchor.geometry)
            
            // 60% 半透明の赤でマテリアルを着色
            plane?.firstMaterial?.diffuse.contents = UIColor.init(red: 1.0, green: 0.0, blue: 0.0, alpha: 0.6)
            
            // 設置しているノードへ処理したジオメトリを渡し描画する
            node.geometry = plane
        }
        
    }
}

 

補足1:非同期

「DispatchQueue.main.async」で非同期の処理を設定しているがメインキューでやる必要性はないので、 普通のシリアルキューでも問題ないと思われる。
(新しい Apple のサンプルではメインキューで使用していない)

 

補足2:ARSCNPlaneGeometry

SCNGeometry のサブクラスなので、SCNGeometrySource と SCNGeometryElement で設定することができるが、
Metal のデフォルトデバイスで初期化し update で更新することができるので簡単。

 

以下の変更が何故か修正され、元に戻った。
次の Beta で変更される可能性あり。

ちなみに現状のドキュメントが変更されている。次の Beta 2 以降変更される可能性がある。
  • init > planeGeometryWithDevice:
  • update > updateFromPlaneGeometry

 

まとめ

以前より少しジオメトリの形状細かく取れるようになったので、 言われているように円のテーブルの平面を円形状に近いジオメトリで取得できるようになったため、 平面に置いた仮想オブジェクトが宙に浮くことが少なくなると思われる。

また、スプラトゥーンの様な領域を埋めた量で競うゲームを現実世界でできることもできるだろう。

 

サンプルコード

github.com

ARKit 1.5 で Vuforia のような画像認識を行う

ARKit 1.5 から Vuforia のような画像認識を行うことができるようになった。
壁や床などの画像を想定しているようなので、現象 Vuforia ほどの正確さはなく、
今後のアップデートで期待したい。

また、公式でサンプルが用意されているため、英語を読むのが苦にならない方は、公式の方を読んでもらった方が良いと思われる。

Recognizing Images in an AR Experience | Apple Developer Documentation

 

ひとまず注意点

  • Beta 版であるため今後仕様が変更される可能性がある
  • Beta 版の Xcode 9.3 使用するため iOS Developer Program 加入している必要がある
  • 端末カメラを使用するため iOS 11.3 をインストールした実機が必要がある
  • Beta 版なので認識がおかしくなることがある
  • 今回は動作部分しか書かないのでエラー処理など追加する必要がある

 

下準備

その1:シーンファイルを消す

既存の Xcode 同様に New Project(Command+Shift+N)から「Augmented Reality App」を選択し、新しいプロジェクトを作成。

今回は AR ではテンプレートとしてつくられる Scene File を使用しないので ViewController.swift の27行目を変更

こちらから

let scene = SCNScene(named: "art.scnassets/ship.scn")!

こちらに変更

let scene = SCNScene()

 

Scene File は必要ないので art.scnassets も消してもらっても構わない。

 

その2:デバッグオプションで特徴点を描画する

この状態が表示しても現実世界のトラッキングか可能にになっているかわからないので、デバッグオプションで特徴点の表示を設定する。 以下のコードを先ほどの 「let scene = 〜」の上らへんに書く

sceneView.debugOptions = [ARSCNDebugOptions.showFeaturePoints]

実機にビルド後、トラッキングが可能になると特徴点が黄色い点として画面に描画される。

 

その3:ARWorldTrackingConfiguration の平面認識設定の追加

viewWillAppear にある「let configuration = ARWorldTrackingConfiguration()」の下に、 以下のものを書き、水平と垂直の平面を認識できるようにする。

configuration.planeDetection = [.vertical, .horizontal]

ひとまず準備完了。

 

制作の流れ

  • 認識させる画像を設定する
  • ARWorldTrackingConfiguration で認識させる画像を渡す
  • ARKit のデリゲート didUpdate でトラッキングが変更されるたび処理する命令を書く
  • DispatchQueue 内で処理をかく
  • アンカーば画像認識用か調べる
  • 取得したノードにジオメトリがあるかないか調べる
  • ジオメトリがない場合は、ジオメトリを設定し ARImageAnchor から大きさとマテリアルを設定する
  • 位置と回転を変更する

 

認識させる画像を設定する

方法は以下の3つ。

  • ARReferenceImage から CGImage で画像を設定する。
  • ARReferenceImage から Core Video の pixel buffer で画像を設定する。
  • アセットカタログに画像をドラッグ&ドロップで設定する

 

今回はアセットカタログから設定する。
Xcode から Assets.xcassets などのアセットを開いてAppIcon の領域で右クリックするか、その左下の「+」ボタン、またはメニューの Editor > Add Assets から「New AR Resource Group」を選択。

AR Resources というグループ名の項目ができるので選択して画像をドロップ。
デフォルトではファイル名が name になる。
ちなみに Size の値を設定しないと画像が認識されないので注意。

 

コードを書く

ARWorldTrackingConfiguration の設定値を追加する

まず、先ほど設定した画像を ARWorldTrackingConfiguration で設定する。
上の方で設定した「configuration.planeDetection = [.vertical, .horizontal]」の下に以下のコードを書く。

configuration.detectionImages = ARReferenceImage.referenceImages(inGroupNamed: "AR Resources", bundle: nil)

inGroupNamed はアセットカタログで作成したグループの名前、bundle は nil にすると Main Bundle からグループ名を検索する。

また、アセットカタログで取得する場合は、外部から読み込まない限り、基本的には画像が見つからないということはないのでエラー処理は省いた。
(detectionImages は Set<ARReferenceImage>? で設定されているため、認識用の画像がなくてもアプリは落ちないので注意)

 

ARKit のデリゲートで処理を書く

今回は画像を上に貼り付けるだけの処理をする。
以下のコード「// MARK: - ARSCNViewDelegate」 の下あたりに書いてビルドすると画像認識が行われる。

// ARKit のデリゲート didUpdate でトラッキングが変更されるたび処理する命令を書く
func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {

    // DispatchQueue 内で処理をかく  
    DispatchQueue.main.async {
        
        // アンカーが画像認識用か調べる
        if let imageAnchor = anchor as? ARImageAnchor {
            
            // ジオメトリが設定されていなければ、ジオメトリを設定
            if(node.geometry == nil){
                let plane = SCNPlane()
                
                // アンカーの大きさをジオメトリに反映させる
                plane.width = imageAnchor.referenceImage.physicalSize.width
                plane.height = imageAnchor.referenceImage.physicalSize.height
                
                // 今回は book2.jpg という画像を認識した画像の上に貼り付ける
                plane.firstMaterial?.diffuse.contents = UIImage(named:"book2.jpg")
                
                // 設置しているノードへジオメトリを渡し描画する
                node.geometry = plane
            }
            
            // 位置の変更
            node.simdTransform = imageAnchor.transform
            
            // 回転の変更
            node.eulerAngles.x = 0
            
        }
        
    }
    
}

 

補足:振る舞い

多分、壁や机など固定された画像に対して画像認識をするケースを想定されており、
認識用の画像に対して複数の画像を使用できないような振る舞いになっている。
(複数できないのは確かドキュメントのどっかに書いてあった気がするが失念。違ったらすみません)

Beta なので今後改善されるだろう。

また、今回は didUpdate のデリゲートを使用しているがアンカーの振る舞いが安定しないため didAdd でも構わないと思う。
公式サンプルでは didAdd の方を使用している。

 

補足:非同期

「DispatchQueue.main.async」で非同期の処理を設定しているがメインキューでやる必要性はないので、普通のシリアルキューでも問題ないと思われる。
(新しい Apple のサンプルではメインキューで使用していない)

 

補足:アニメーションするジオメトリを置く際の注意

float 4x4 の行列で返ってくるため、回転などのアニメーションするノードにそのまま渡すと動きがおかしくなる可能性がある。
その場合は空のノードにアニメーションをさせて、それを addChild した方が良いと思われる。

 

まとめ

美術館などで作品の説明をしたり、ゲームなどでアイテムを表示するなど、現実世界を AR で描き返る参照となり、様々なものに利用できる。

また、画像を初期位置とし他の端末と場所の共有や各端末の振る舞いの共有などもできるかもしれない。
リアルと仮想空間をミックスした空間共有というのもの面白いと思われる。

 

サンプルコード

github.com

ARKit 1.5 での変更点 (Xcode 9.3 Beta / iOS 11.5 Beta )

Beta なので公開されている情報からのまとめ。
NDA 上スクリーンショットが出せないので今回も文字だけ。

以下の情報に関しては今後変更される可能性があるため注意が必要。

 

主な変更

www.moguravr.com

 

  • 垂直方向平面の認識
  • 画像認識
  • 以前よりも細かな形状認識
  • カメラのオートフォーカス
  • カメラ解像度が 720p から 1080i に変更

 

以下 SDK の変更

「CVarArg, Equatable, Hashable」など Relationships の Conforms To 部分での変更は割愛。

API の和訳だけでは分かりづらいので、次回以降で以下のサンプルの動作を説明予定。

github.com

github.com

 

追加

ARSession

func setWorldOrigin(relativeTransform: matrix_float4x4)

float4x4 の行列を使用し、ARKit のワールド座標の原点を変更する。
デフォルトは端末がアプリを起動した場所。

https://developer.apple.com/documentation/arkit/arsession/2942278-setworldorigin

 

ARSessionObserver

func sessionShouldAttemptRelocalization(ARSession)

ワールドトラッキング中断後に状態回復を試みるかどうかを delegate から問い合わせる。
関数を実装して true を返すと、再開後 ARKit はワールドトラッキング状態を調整しようとするとのこと。

再開できなかった時のためにセッションの run メソッドで resetTracking を設定しトラッキングをやり直せるようにした方がよい。
ちなみに中断から再開する場合、端末がトラッキング失敗した場所の付近で行うと成功しやすいとのこと。

https://developer.apple.com/documentation/arkit/arsessionobserver/2941046-sessionshouldattemptrelocalizati

 

ARWorldTrackingConfiguration

vertical (ARWorldTrackingConfiguration.PlaneDetection)

ARWorldTrackingConfiguration の PlaneDetection でこちらを選択すると垂直方向への検知ができるようになる。
horizontal を共に使用して、垂直と水平の状態を検知することも可能。

https://developer.apple.com/documentation/arkit/arworldtrackingconfiguration.planedetection/2867271-vertical

 

detectionImages

画像認識用で検知するためのリファレンスとなる画像を ARReferenceImage を使用して設定する。
ここで設定した画像がカメラからキャプチャした画像内にあれば ARImageAnchor を置くように設定できる。
リファレンスとなる画像は複数枚設定可能。

https://developer.apple.com/documentation/arkit/arworldtrackingconfiguration/2941063-detectionimages

 

isAutoFocusEnabled

カメラのオートフォーカスを使用するか設定する。
デフォルトで true になっており、オートフォーカスを行う。

https://developer.apple.com/documentation/arkit/arworldtrackingconfiguration/2942262-isautofocusenabled

 

AROrientationTrackingConfiguration

isAutoFocusEnabled

ワールドトラッキング同様にカメラのオートフォーカスを使用するか設定する。

https://developer.apple.com/documentation/arkit/arorientationtrackingconfiguration/2942263-isautofocusenabled

 

ARPlaneAnchor

vertical (ARPlaneAnchor.Alignment)

ARPlaneAnchor の Alignment が vertical の場合、アンカーは重力に対して平行の回転を返す。
また、Alignment からアンカーとして置いた平面が 垂直か水平かどうか調べることができる。
(水平、垂直、互いに重力に対して平行の行列を返すのでコンテンツによっては、垂直または水平で向きを変えなければならなくなる)

https://developer.apple.com/documentation/arkit/arplaneanchor.alignment/2865598-vertical

 

geometry

以前の ARPlaneAnchor は検知した領域は矩形だったが、 geometry はアンカーが検知した平面の形に合わせた多角形のポリゴンの情報を ARPlaneGeometry として提供される。

SceneKit 用にラッパークラスである ARSCNPlaneGeometry が用意されている。

https://developer.apple.com/documentation/arkit/arplaneanchor/2941025-geometry

 

ARPlaneGeometry

アンカーが検知した平面の形に合わせた多角形のポリゴン(三角ポリゴンのメッシュ)として描画する。
SceneKit のカスタムジオメトリ生成する際に必要な値、検知した領域を多角形のポリゴンを囲う境界の頂点を取得できる。

パラメーターは以下のもの。
ほとんどの場合 ARSCNPlaneGeometry を使用すると思われるので詳細は割愛。

  • vertices: [vector_float3]
  • textureCoordinates: [vector_float2]
  • triangleCount: Int
  • triangleIndices: [Int16]
  • boundaryVertices: [vector_float3]

https://developer.apple.com/documentation/arkit/arplanegeometry

 

ARSCNPlaneGeometry

SCNGeometry のサブクラス。
ARPlaneGeometry クラスのメッシュデータの値をラップし、形状を描画する。
OpenGL での使用はできない。

ARSCNPlaneGeometry を使用すると、ARPlaneAnchor の geometry によって提供された平面形状を update(from:) の設定するだけで形状の描画をおこなってくれる。
また、delegate の update 内でジオメトリの設定しないと形状が変わらないので注意。

https://developer.apple.com/documentation/arkit/arscnplanegeometry

 

ARReferenceImage

画像認識用のリファレンス用の画像を設定し、上記の ARWorldTrackingConfiguration の detectionImages に渡すと動作するようになる。
(リファレンス用の画像の大きさを設定しないとマッチさせる画像の大きさが 0 となりの認識されないので注意)

 

class func referenceImages(inGroupNamed: String, bundle: Bundle?)

inGroupNamed はアセットカタログで作成した「AR Resource Group」の指定、bundle はバンドルの場所を示す。bundle が nil の場合は main bundle。
アセットカタログで設定する際は以下の name と physicalSize は Xcode のインスペクタ上で設定できる。

 

var name: String?

設定した画像の名前。
認識した画像毎に何かしたい場合は名前で判別させる。

 

var physicalSize: CGSize

画像認識した際のワールド空間での大きさを返す。

 

init(CGImage, orientation: CGImagePropertyOrientation, physicalWidth: CGFloat)

アセットカタログを使用せず CGImage からリファレンス用の画像を設定する。

 

init(CVPixelBuffer, orientation: CGImagePropertyOrientation, physicalWidth: CGFloat)

アセットカタログを使用せず、動画などの CVPixelBuffer からリファレンス用の画像を設定する。

https://developer.apple.com/documentation/arkit/arreferenceimage

 

ARImageAnchor

現実世界で画像検索し画像認識後返される画像認識版アンカー。
transform で位置や回転を取得し、referenceImage(ARReferenceImage)の physicalSize で大きさを取得する。

 

var referenceImage: ARReferenceImage

ARReferenceImage として返される。

https://developer.apple.com/documentation/arkit/arimageanchor

 

ARHitTestResult

static var estimatedVerticalPlane: ARHitTestResult.ResultType (ARHitTestResult.ResultType)

タップなどのヒットテスト時に、垂直面だと予測される位置の結果を返す。

https://developer.apple.com/documentation/arkit/arhittestresult.resulttype/2887455-estimatedverticalplane

 

existingPlaneUsingGeometry (ARHitTestResult.ResultType)

existingPlaneUsingExtent とは異なり予測される大きさと形を返す。

https://developer.apple.com/documentation/arkit/arhittestresult.resulttype/2942264-existingplaneusinggeometry

 

ARCamera.TrackingState.Reason

case relocalizing

ARCamera の TrackingState で何らかの中断後トラッキング再開している状態。

https://developer.apple.com/documentation/arkit/arcamera.trackingstate.reason/2949172-relocalizing

 

追加要素不明

ARError

static func != (lhs: ARError, rhs: ARError) -> Bool

ステータスは追加となっているが何が追加されたのかわからない。

 

変更不明

  • ARSession.RunOptions
  • ARFaceAnchor.BlendShapeLocation
  • ARSCNView / ARSCNViewDelegate
  • ARSKView / ARSKViewDelegate
  • ARCamera / static func != (lhs: ARCamera.TrackingState.Reason, rhs: ARCamera.TrackingState.Reason) -> Bool

 

変更(ドキュメント追記 SDKs Xcode 9.3+)

  • ARError.errorCode
  • ARError.errorUserInfo
  • ARError.localizedDescription
  • ARError.cameraUnauthorized
  • ARError.errorDomain
  • ARError.sensorFailed
  • ARError.sensorUnavailable
  • ARError.unsupportedConfiguration
  • ARError.worldTrackingFailed
  • ARFrame > ARPointCloud > points
  • ARFrame > ARPointCloud > identifiers
  • ARCamera > trackingState

Xcode 9.3 beta.1 での SceneKit の変更

今回 SceneKit の API 的には何も変わっていない。

Hashable プロトコル hashValue に SDK の Xcode 7.1+ が追加されたため、内容が変わっていないものでも Modified(変更)がかかっている様子。

一応、まとめてみた。

 

Added

CVarArg, Equatable, Hashable

  • SCNText
  • SCNShape
  • SCNFloor
  • SCNBox
  • SCNCapsule
  • SCNCone
  • SCNCylinder
  • SCNPlane
  • SCNPyramid
  • SCNSphere
  • SCNTorus
  • SCNTube
  • SCNBillboardConstraint
  • SCNLookAtConstraint
  • SCNDistanceConstraint
  • SCNAvoidOccluderConstraint
  • SCNAccelerationConstraint
  • SCNSliderConstraint
  • SCNReplicatorConstraint
  • SCNIKConstraint
  • SCNTransformConstraint
  • SCNPhysicsSliderJoint
  • SCNPhysicsBallSocketJoint
  • SCNPhysicsConeTwistJoint
  • SCNPhysicsVehicle

 

Modified

  • SCNLayer / CVarArg, Equatable, Hashable, SCNSceneRenderer, SCNTechniqueSupport

SDKs > Xcode 7.1+

  • SCNNode / SCNBoundingVolume / boundingBox
  • SCNNode / SCNBoundingVolume / boundingSphere

変更不明

  • SCNScene.Attribute / SCNView.Option
  • SCNView / SCNView.Option
  • SCNSceneRenderer / SCNHitTestOption
  • SCNSceneRenderer / SCNDebugOptions
  • SCNLight / SCNLight.LightType
  • SCNMaterial / SCNMaterial.LightingModel
  • SCNMaterial / SCNColorMask
  • SCNGeometrySource / SCNGeometrySource.Semantic
  • SCNBillboardConstraint / SCNBillboardAxis
  • SCNPhysicsBody / SCNPhysicsCollisionCategory
  • SCNPhysicsShape / SCNPhysicsShape.Option / SCNPhysicsShape.ShapeType
  • SCNPhysicsWorld / SCNPhysicsWorld.TestOption / SCNPhysicsWorld.TestSearchMode
  • SCNParticleSystem / SCNParticleSystem.ParticleProperty
  • SCNShadable / SCNShaderModifierEntryPoint
  • SCNSceneSource / SCNSceneSource.LoadingOption / SCNSceneSource.AnimationImportPolicy

2018年からの XR (AR/MR/VR) について考える

XR とは Augmented Reality (AR)、Mixed Reality (MR)、Virtual Reality (VR) などの総称である。

ざっくりまとめるとこんな感じ

名称 対応技術
Augmented Reality (AR) ARKit(iOS), ARCore(Android), Vufolia, その他
Mixed Reality (MR) Microsoft HoloLens, Windows Mixed Reality, その他
Virtual Reality (VR) Oculus Rift, HTC Vive, Gear VR, Google VR (Daydream, Cardboard), その他

 

去年からの流れ

VR がいろいろなところで見られるようになったが、やはり機材が高いため体験するためのコストが高く、一般的には VR ZONE などのアトラクション施設や展示会、特定の業務などで使用されるケースがほとんどだった。
また、初期から行なっているインディー系の人たちの VR への熱意は素晴らしい。
ただ、コンテンツのクオリティが上がってきており、制作コストの増加に伴いそれに見合う収益が出るかなど厳しい局面に立たされるのではないかと予想される。

AR に関してはスマートフォンを主軸としたものになるだろうけど、現状では始まったばかりな感じ。
Android の ARCore はまだプレビューで対応機種が少なく、 iOS の ARKit に関しては現状では機能が少なすぎて AR を活かしきるアプリをつくることが難しい。
これら2つに関しては多分今年アップデートされると思われるのでそれを期待したい。

 

今後来る流れ

VR、MR の方は体験できる人が限られるので、ひとまず今回はスマートフォンの AR 方を主軸として考えていく。

 

3DCG の表現や画質の向上

SoC などチップの向上により、更なる表現の向上が可能になると思われる。
また、以下の動画ではリアルタイムでグローバルイルミネーションが実装されている。
NVIDIA の GTX850M で 50fps とのことなので、次期 iPad, iPhone では普通に動かすことが可能な感はある。

 

www.youtube.com

- グローバルイルミネーションの雑な説明 -
現実世界では物体が色を持っているわけではなく、光から特定の色を反射させている。
りんごの赤以外を吸収して赤色を反射しているため、白い紙の上に置くと紙との接地面が若干赤くなる
この光の特性をコンピューターで計算するとかなり時間がかかるためリアルタイムでは難しかった

 

センサーの強化

現状、モバイルではどうなるかわからないが Kinect の強化版が開発されている。
個人的には人間の目を模倣するべきだと思っており SLAM や2眼カメラの技術の進化を期待しているが、モバイル端末に Kinect のようなものが載っても面白い。
Google Tango の後継機が出ないので今後どうなるかは不明だが。

 

shiropen.com

shiropen.com

 

触覚センサーなどの外部センサーやフィードバック

身体的に体感するため、本体とは別デバイスがいくつか登場すると思われる。
現状でも、ARKit と Apple Watch の組み合わせで Apple Watch 側の加速度センサーからの手の動きや心拍計からデータは取れそうではある。

 

shiropen.com

shiropen.com

 

また、現在日本を開発拠点にしているベンチャー VAQSO VR が匂いの出るセンサーを開発している。
Bluetooth で接続され、匂いは1日2時間の使用で1ヶ月使えるとのこと

vaqso.com

 

画像生成

カメラから得られた情報から擬似的に画像や映像を生成することができるのではないかと思っている。
良い例は NVIDIA での画像生成。

shiropen.com

 

画像合成モデルを生成できるのであれば、 解像度に依存しない画像の生成も行うことができるのではないかと思われる。

  

画像認識からの空間共有

画像とセンサー類を使用して位置を合わせることができると思われるので、複数人で空間を共有できると思われる。

Bloomberg 曰く、ARKit 2.0 ではこのような機能が付くのではないか、とのこと。

 

計算や機械学習を使用したモデリングやパターンから生成するプローシージャルモデリング

ゲームでのオープンフィールドなど多量に派生しなければいけないものなど、 ある程度自動的に生成されないと厳しいだろう。 また、ランダムで生成される商品など新しい魅力を提示できるかもしれない。

shiropen.com

 

物体や現実空間への情報提示

Vuforia SDK 4.0 などで現実空間の3次元オブジェクトをマカーにして表示している。

www.youtube.com

 

また、Google Lens や ARKit と Core Location など、 位置情報と周囲の情報の連携が今後強化されるのではないかと思われる。

www.youtube.com

 

AR / VR 間でのスイッチ

スマートフォンが Web やネットワークをつなぐ架け橋となるのなら、 AR は外界とをつなぐものである。

現実空間から仮想空間へモノを渡したり、仮想空間から現実空間へモノを渡したりなど、
もし、外界と仮想空間が行き来できたとしたら面白いだろう。

 

その他

VR に関しては視線を遮ってしまうため、以下のような事故が起こる。 VR でも外界を認識して危険を知らせる必要があるようだ。

www.moguravr.com

 

Xcode 9.2 での SceneKit の変更点

今更だけど、書き忘れていた。

 

Xcode 9.1 から Xcode 9.2 での変更は1つ。

SCNSceneSource.LoadingOption のタイププロパティ useSafeMode が廃止予定となった。

useSafeMode - SCNSceneSource.LoadingOption | Apple Developer Documentation

 

SCNSceneSource.LoadingOption は、ほぼ紹介していなかったと思われるが、
scn などシーンファイルを Y 軸の方向を変更して読み込むなどのオプションを設定できる。

 

今回、廃止予定のタイププロパティ useSafeMode とは?

設定値は Boolean を含む NSNumber で true に設定すると ネットワークなどの外部や扱いに注意が必要なローカルのディレクトリからリソースを読み込む負荷の設定にすることができる。

 

まとめ

廃止になった理由は不明だが、
SCNSceneSource でシーンのリソースを読み込む場合、読み込むリソース自体を開発者が選択しプログラムを書いているため、このプロパティをあまり必要性がないと感じたのかもしれない。