Unity で周囲の建物や地形を使用する

Streetscape Geometry API は、シーン内の地形、建物、その他の構造物のジオメトリを提供します。このジオメトリは、ヒットテスト API を介してオクルージョン、レンダリング、AR コンテンツの配置に使用できます。ストリートビュー ジオメトリ データは、Google ストリートビュー画像から取得したものです。

サンプルを試す

Geospatial サンプルアプリでは、街並みのジオメトリを取得してレンダリングする方法を示しています。

Geospatial API を設定する

街並みのジオメトリを使用するには、プロジェクトで Geospatial API を設定する必要があります。Geospatial API の有効化の手順に沿って、Geospatial API を設定します。

街並みのジオメトリを有効にする

Geospatial API は、GeospatialModeGeospatialMode.Enabled に設定され、StreetscapeGeometryModeStreetscapeGeometryMode.Enabled に設定されている場合に、Streetscape Geometry データを取得します。

ARCore セッションで街並みのジオメトリを取得する

ARStreetscapeGeometryManager コンポーネントを GameObject に追加します。ストリートビュー ジオメトリが追加、更新、削除されると、ARStreetscapeGeometryManager.StreetscapeGeometriesChanged イベントがトリガーされます。

public Material streetscapeGeometryMaterial;

List<ARStreetscapeGeometry> _addedStreetscapeGeometries = new List<ARStreetscapeGeometry>();
List<ARStreetscapeGeometry> _updatedStreetscapeGeometries = new List<ARStreetscapeGeometry>();
List<ARStreetscapeGeometry> _removedStreetscapeGeometries = new List<ARStreetscapeGeometry>();

public void OnEnable()
{
    StreetscapeGeometryManager.StreetscapeGeometriesChanged +=
        GetStreetscapeGeometry;
}

public void Update() {
  foreach (ARStreetscapeGeometry streetscapegeometry in _addedStreetscapeGeometries)
  {
    GameObject renderObject = new GameObject(
       "StreetscapeGeometryMesh", typeof(MeshFilter), typeof(MeshRenderer));

    if (renderObject)
    {
        renderObject.transform.position = streetscapegeometry.pose.position;
        renderObject.transform.rotation = streetscapegeometry.pose.rotation;
        renderObject.GetComponent<MeshFilter>().mesh = streetscapegeometry.mesh;
        renderObject.GetComponent<MeshRenderer>().material = streetscapeGeometryMaterial;
    }
  }
}

public void OnDisable()
{
    StreetscapeGeometryManager.StreetscapeGeometriesChanged -=
        GetStreetscapeGeometry;
}

private void GetStreetscapeGeometry(ARStreetscapeGeometriesChangedEventArgs eventArgs)
{
    _addedStreetscapeGeometries = eventArgs.Added;
    _updatedStreetscapeGeometries = eventArgs.Updated;
    _removedStreetscapeGeometries = eventArgs.Removed;
}

ARStreetscapeGeometry について

ARStreetscapeGeometry には、建物に関する情報が含まれます。

建物の LOD 1

BuildingLOD1 は、平らな上部まで上向きに押し出された建物のフットプリントで構成されます。建物の高さが正確でない場合があります。

LOD 2 のビルド

BuildingLOD2 のジオメトリの忠実度が向上します。メッシュの壁と屋根は、建物の形状に近づきます。煙突や屋根の通気口などの小さい対象物は、メッシュの外側に突く可能性があります。

Mesh について

Mesh は「ストリートビュー ジオメトリ」の表面再構築を表すポリゴン メッシュです。 MeshMeshRenderer をご覧ください。デフォルトでは法線は計算されません。法線を計算するには、Mesh.RecalculateNormals() をご覧ください。

AR コンテンツを ARStreetscapeGeometry に添付する

ARAnchorManager.AddAnchor() を使用して、ARStreetscapeGeometry.mesh の頂点付近にある特定のポーズにアンカーを作成します。このアンカーは、親の ARStreetscapeGeometry からトラッキング状態を継承します。

ARStreetscapeGeometry に対してヒットテストを実行する

ARRaycastManagerExtensions.RaycastStreetscapeGeometry を使用すると、ストリートビュー ジオメトリに対してヒットテストを行うことができます。交差点が検出されると、XRRaycastHit には、ヒットした位置に関するポーズ情報と、ヒットした ARStreetscapeGeometry への参照が含まれます。このストリートビュー ジオメトリを ARAnchorManager.AddAnchor() に渡して、それに関連付けられたアンカーを作成できます。

Vector2 screenTapPosition = Input.GetTouch(0).position;
List<XRRaycastHit> hitResults = new List<XRRaycastHit>();
if (RaycastManager.RaycastStreetscapeGeometry(screenTapPosition, ref hitResults)){
  ARStreetscapeGeometry streetscapegeometry =
      StreetscapeGeometryManager.GetStreetscapeGeometry(hitResults[0].trackableId);
  if (streetscapegeometry != null)
  {
      ARAnchor anchor = StreetscapeGeometryManager.AttachAnchor(streetscapegeometry, hitResults[0].pose);
  }
}

Geospatial Depth を有効にする

Geospatial Depth は、Streetscape Geometry とローカル センサー入力を組み合わせて、深度データを補正します。Geospatial Depth が有効になっている場合、出力の深度画像と元の深度画像が変更され、ローカルで測定された深度に加えて、ラスター化された Streetscape Geometry が含まれます。これにより、デプスを使用したポーズの精度が向上する可能性があります。