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

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

サンプルを試す

地理空間サンプルアプリは、ストリートビュー ジオメトリを取得してレンダリングする方法を示しています。

Geospatial API を設定する

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

ストリートビュー ジオメトリを有効にする

Geospatial API は、GeospatialModeGeospatialMode.Enabled に、StreetscapeGeometryModeStreetscapeGeometryMode.Enabled に設定されている場合、ストリートビュー ジオメトリ データを取得します。

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 は、ストリートビュー ジオメトリとローカル センサー入力を組み合わせて、奥行きデータを強化します。Geospatial Depth を有効にすると、出力深度と未加工の奥行きの画像が変更され、ローカルで観測された深度に加えて、ラスター化されたストリートビュー ジオメトリが含まれるようになります。これにより、奥行きを使用したポーズの精度が向上する可能性があります。