見出し画像

サンプルからひも解くImmersal

ARクラウドとして強力な Immersal の検証を行います。
今回はサンプルプロジェクトを実際に動かしていきます。

導入までは下記ドキュメントの手順通りです。
今回は割愛します。
Getting Started

バージョン・環境情報

Unity 2019.4.8f1
Immersal SDK 1.7.0
Immersal Mapper 1.7.0

撮影時の天候 曇り

画像1

1.マップを作成する

下記ドキュメントの注意点に従ってマップを作成します。
How To Map

実際に作成したマップデータをglbファイル形式で出力したものがこちらです。

Immersal教会-1

このマップ作成においては15枚しか撮影を行っていません。
マップ作成を正しい撮影方法で行えば、はっきりとした特徴点抽出が行えます。

このglbファイルは自前で変換の処理を挟まなくともマップ作成後自動的に出力され、開発者ポータルにアップロードされます。

2.作成したサンプルにマップを埋め込む

今回利用するサンプルシーンは下記です。
Assets/ImmersalSDK/Samples/Scenes/ContentPlacementSample

先程作成したマップのbytes形式のデータをポータルからダウンロードしてサンプルプロジェクトの中にインポートします。
ちなみにこちらの点群データはたったの220KBでした。

画像3

下記画像のMapFileにインポートしたマップデータをアタッチすれば準備完了です。

画像4

3.実際に動かしてみる

実機でのデモ動画になります。

デモの内容は下記です。
①特徴点からマップのマッチング処理開始
②マップ認識後、3D空間にダイヤモンドを配置
③端末内にダイヤモンドの位置情報を保存
④アプリを再度立ち上げた際にダイヤモンドを再配置

非常に精度が高いことが見て取れます。

4.マップから離れた場合を確認する

一時的にマップから離れて再度認識合わせを行った場合の挙動を確認してみました。

約20m程歩行してから再度認識位置に戻っています。

マップの認識範囲にカメラの画角が収まった瞬間に正確に位置合わせが行われました。

サンプルシーンで行われている処理について

サンプルシーン上で行われている処理について簡単に解説します。

マップを内包する1つのAR空間がオブジェクトとして定義されています。
ダイヤモンドはAR空間の子オブジェクトとして空間に生成されます。

ここまでの説明を図に落とし込むと下記画像のような状態です。

画像5

今回のサンプルシーン内のコードを見るとより理解が深まります。

下記はダイヤモンドの配置に関する ContentStorageManager クラス内のコードです。

public void AddContent()
{
   Transform cameraTransform = Camera.main.transform;
   GameObject go = Instantiate(m_ContentPrefab, cameraTransform.position + cameraTransform.forward, Quaternion.identity, m_ARSpace.transform);
}

public void SaveContents()
{
   m_Positions.Clear();
   foreach (MovableContent content in contentList)
   {
       m_Positions.Add(content.transform.localPosition);
   }
   m_Savefile.positions = m_Positions;

   string jsonstring = JsonUtility.ToJson(m_Savefile, true);
   string dataPath = Path.Combine(Application.persistentDataPath, m_Filename);
   File.WriteAllText(dataPath, jsonstring);
}

public void LoadContents()
{
   string dataPath = Path.Combine(Application.persistentDataPath, m_Filename);

   try
   {
       Savefile loadFile = JsonUtility.FromJson<Savefile>(File.ReadAllText(dataPath));

       foreach (Vector3 pos in loadFile.positions)
       {
           GameObject go = Instantiate(m_ContentPrefab, m_ARSpace.transform);
           go.transform.localPosition = pos;
       }
   }
   catch (FileNotFoundException e)
   {
       Debug.LogError(dataPath + " not found\nNo objects loaded: " + e.Message);
   }
}

AddContent メソッドの中でダイヤモンドの生成処理を行っています。
AR Space (AR空間として扱われるオブジェクト)の子階層に配置しているのがわかります。

その後の SaveContents メソッド内ではダイヤモンドのローカルポジションをJson形式として保存しています。

LoadContents メソッドにおいては再度ダイヤモンドをAR Spaceの子階層に配置し、先程のJson形式で保存したローカルポジションを適用して復元しています。

この一連の処理から、ARコンテンツを作成する際にはARオブジェクトを AR Space (AR空間として扱われるオブジェクト)の子階層の任意のローカル座標に配置すれば良いことがわかりました。

事前に任意の位置に細かく合わせて出現させたい時などはglbファイルをUnityエディターにインポートして視覚的に配置する、もしくはAR空間に配置したオブジェクトの座標を記録しておく配置ツールなどを作成するのも良いかもしれません。

まとめ

Immersal は簡単にARコンテンツの開発ができる上に、精度が高いので、開発者にとって非常に使いやすいツールであると感じました。

Nreal にも対応したようなので、今後はスマートグラスのARコンテンツ開発においてもより一層強力なツールとなりそうなので要注目です。

この記事が気に入ったらサポートをしてみませんか?