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

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

サンプルを試す

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

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 が含まれます。これにより、デプスを使用したポーズの精度が向上する可能性があります。