見出し画像

ARMeshGeometryをSceneKitで(RealityKitを使わず)描画する

AppleのScene ReconstructionサンプルはRealityKitを利用してめちゃくちゃ簡単にカッコいい可視化を実現している。

具体的には次の1行。

arView.debugOptions.insert(.showSceneUnderstanding)

これだけでLiDARを用いて検出したメッシュがカッコよく可視化されている。

画像1

これをRealityKitを使わず、ARKit+SceneKitで実現したい場合、ここまで簡単にはいかない。


## ARMeshGeometry

ARMeshGeometryは以下のように定義されているクラス:

open class ARMeshGeometry : NSObject, NSSecureCoding {

   
   /*
    The vertices of the mesh.
    */
   open var vertices: ARGeometrySource { get }

   
   /*
    The normals of the mesh.
    */
   open var normals: ARGeometrySource { get }

   
   /*
    A list of all faces in the mesh.
    */
   open var faces: ARGeometryElement { get }

   
   /*
    Classification for each face in the mesh.
    */
   open var classification: ARGeometrySource? { get }
}

で、ARGeometrySource, ARGeometryElementの定義はこんな感じ:

open class ARGeometrySource : NSObject, NSSecureCoding {
   open var buffer: MTLBuffer { get }
   open var count: Int { get }
   open var format: MTLVertexFormat { get }
   open var componentsPerVector: Int { get }
   open var offset: Int { get }
   open var stride: Int { get }
}
open class ARGeometryElement : NSObject, NSSecureCoding {

   open var buffer: MTLBuffer { get }
   open var primitiveType: ARGeometryPrimitiveType { get }
   open var count: Int { get }
   open var bytesPerIndex: Int { get }
   open var indexCountPerPrimitive: Int { get }
}

前述した通り、データが格納されているバッファがMTLBufferであることがポイント。

## ARMeshGeometryをRealityKitを使わず可視化する方法(案)3つ

そんなARMeshGeometryを可視化する方法として、以下の3つが思い浮かんだ。

1. ARMeshGeometry(の各プロパティが持つARGeometrySource, ARGeometryElementオブジェクトのバッファ)をそのままMetalで描画する
2. ARMeshGeometryをMTKMeshに変換してMetalで描画
3. ARMeshGeometryをSCNGeometryに変換してSceneKitで描画

1がもっとも柔軟性が高く本質的な解決方法だが、もっともめんどくさい。もっと簡単な方法があるならそちらを取りたい。

2は1と同様にMetalでの描画でありつつ、MTKMeshというクラスによりメッシュの取り扱いが簡単になってそうなので一見「いいとこどり」な気がしたが、MTKMeshのイニシャライザを見るとMDLMeshオブジェクトを渡すことになっていて、

init(mesh: MDLMesh, device: MTLDevice) throws

そのMDLMeshのイニシャライザの一覧を見てみると、いずれを使うにしてもMTLBufferからいったんCPU側でデータを吸い出してMDLMeshを初期化する感じになりそうなので、

だったらARMeshGeometryをSCNGeometryに変換(@CPU)してSceneKitで描画(@GPU)する案3の方が簡単だしパフォーマンス面でのトレードオフもないんじゃないの、という考えに至った。

## サンプルコード


ここから先は

0字 / 1ファイル
文章やサンプルコードは多少荒削りかもしれませんが、ブログや書籍にはまだ書いていないことを日々大量に載せています。たったの400円で、すぐに購読解除してもその月は過去記事もさかのぼって読めるので、少しでも気になる内容がある方にはオトクかと思います。

技術的なメモやサンプルコード、思いついたアイデア、考えたこと、お金の話等々、頭をよぎった諸々を気軽に垂れ流しています。

最後まで読んでいただきありがとうございます!もし参考になる部分があれば、スキを押していただけると励みになります。 Twitterもフォローしていただけたら嬉しいです。 https://twitter.com/shu223/