2018~2019年の年末年始休暇を使って、スマホ単眼カメラで空間認識ができるSDK、6d.aiを触ってみたのでメモを残しておきます。
ARでにゃんこをしまっちゃうおじさんした。
(ブロックサイズを10cmにしてテクスチャつけた)よし! #大晦日ハッカソン はこれで終了。#6D_AI #Unity pic.twitter.com/yVLHym3ojw
— とりカシュ (@torikasyu) December 31, 2018
まずは、サンプルシーンを眺めるところから始めてみました。
Basic Sceneでは、オブジェクトをSLAMで認識した部屋の形状に合わせて配置・移動し、その状態をクラウドに保存することができます。
その移動できるオブジェクトにアタッチされているソースコードの中身を見ていくと、6d.aiの基本的な使い方が見えてきました。
下記は、オブジェクトがドラッグされた時の位置を決定している部分です。
if (Physics.Raycast(ray, out hit, maxDistance, 1 << SixDegrees.SDMesh.MeshLayer)) { // intersect with the mesh, raise by a couple centimeters transform.position = hit.point + new Vector3(0f, 0.02f, 0f); }
Raycastを、SixDegrees.SDMesh.MeshLayerに対して実行しています。SixDegrees.SDMesh.MeshLayerの値は「9」が入っています。
つまり、空間認識された部屋の形状は、9番のレイヤーにUnityの座標系でそのまま格納されている、ということになります。
ARKitやARCoreでは、ARの空間はUnityの空間とは異なるものなので、座標系の変換が必要でした。
それに対して、6d.aiは変換の必要がありません。
HoloLensの開発をしたことがある人でしたらば、SpatialMappingの上にオブジェクトを置いたり、当たり判定を取ったり、という操作をされたと思いますが、考え方としてはARKitよりもずっとそちらに近いです。
サンプルのBall Pit Sceneでも、認識した空間は特にプログラムをすることなくColliderを持っていて、投げたボールが床や壁などに反応する、という作りになっています。
ということで、上記のコードは、認識した部屋の床から2cm浮かせたところにオブジェクトを移動する、という意味になります。
とてもわかりやすいSDKですね。
ということで、改造して下記のようなものを作ってみました。
#6D_AI で作ったARマイクラ風、ブロック削除機能つけたらだいぶ楽しくなった。オクルージョンがHoloLensに比べて若干汚い(椅子の背のところ)けど、単眼カメラでこれはすごい。 pic.twitter.com/HlHgUdT46D
— とりカシュ (@torikasyu) January 2, 2019
完全にマイクラですが、動きとしては、床や壁などをタップするとその場所にブロックが生成され、ブロックをタップするとその隣にまたブロックが生成されるというものです。
床をタップするとブロックが生成される、というのは下記のコードとなります。
Ray ray = mainCamera.ScreenPointToRay(tapPosition); if (Physics.Raycast(ray, out raycastHit, maxDistance, 1 << SixDegrees.SDMesh.MeshLayer) && raycastHit.distance >= minDistance) { Vector3 spawnPoint = raycastHit.point + raycastHit.normal * blockSize; spawnPoint = Snap(spawnPoint); var block = Instantiate(prefabBlock, spawnPoint, Quaternion.identity); }
tapPositonはInput.GetTouch()から得られる、タッチしたスクリーンの座標になります。
ScreenPointToRayでRayを作成し。SixDegrees.SDMesh.MeshLayerとの交点を求めて、その少し上(というか内側)にブロックを生成しています。
Snap()は、ブロックの座標をマス目単位にするための自作の関数です。(基準単位で各座標を割った結果の整数に基準単位を掛け算する)
ブロックがタップされた時は同じようにブロックのnormal方向に単位分ずらしてInstantiateします。
上記のように、非常に直感的に、現実空間をあまり意識することなく、Unityの空間内だけで完結しているような書き方ができるので、とてもプログラムしやすいという感想でした。
サンプルを動かしたときも感じたのですが、単眼カメラでHoloLens並みの空間認識と安定性を持った6d.ai、まだベータ版なのでこれからの進化がとても楽しみです。