ARMeshGeometryをSceneKitで(RealityKitを使わず)描画する
AppleのScene ReconstructionサンプルはRealityKitを利用してめちゃくちゃ簡単にカッコいい可視化を実現している。
具体的には次の1行。
arView.debugOptions.insert(.showSceneUnderstanding)
これだけでLiDARを用いて検出したメッシュがカッコよく可視化されている。
これを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の方が簡単だしパフォーマンス面でのトレードオフもないんじゃないの、という考えに至った。
## サンプルコード
最後まで読んでいただきありがとうございます!もし参考になる部分があれば、スキを押していただけると励みになります。 Twitterもフォローしていただけたら嬉しいです。 https://twitter.com/shu223/