現実世界の場所にコンテンツを固定する

対象となる XR デバイス
このガイダンスは、次のようなタイプの XR デバイス向けのエクスペリエンスを構築する際に役立ちます。
有線 XR グラス

アンカーの一種である Geospatial アンカーを使用すると、Geospatial API を使用して地理座標を持つ 3D コンテンツを配置できます。

地理空間アンカーは、緯度と経度を使用して位置を決定します。緯度と経度は WGS84 仕様で定義されています。これは、一般的な GPS システムに表示される座標と同じです。

場所の緯度と経度を特定する

特定のスポットを念頭に置いている場合は、Google マップを使用して緯度と経度を特定します。

  1. デスクトップ パソコンで Google マップにアクセスします。
  2. [レイヤ] > [その他] に移動します。

    Google マップのレイヤボタン

    Google マップの [もっと見る] ボタン

  3. [地図の種類] を [航空写真] に変更し、画面の左下にある [地球表示] チェックボックスをオフにします。

    Google マップの地図の種類のオプション

    これにより、2D の視点が強制され、角度のある 3D ビューで発生する可能性のあるエラーが排除されます。

  4. 地図上で場所を右クリックし、緯度と経度を選択してクリップボードにコピーします。

ユーザーのエリア内の位置を Geospatial アンカーに変換する

対象のスポットに移動できる場合は、デバイスローカルのポーズを Geospatial のポーズに変換することで、ローカルの読み取り値から緯度、経度、高度を特定できます。

地理空間アンカーにコンテンツを配置する

地理空間アンカーには、WGS84 楕円体、地形、または屋上を基準とした高度値が必要です。

  • WGS84 楕円体に対する高度値には、Geospatial.createAnchor を使用します。

    val createAnchorResult = geospatial.createAnchor(
        latitude,
        longitude,
        altitude,
        Quaternion.Identity,
    )

  • 地形または屋上を基準とした高度値には、Geospatial.createAnchorOnSurface を使用します。GeospatialSurface.TERRAIN と GeospatialSurface.ROOFTOP をそれぞれ使用して、最終的な高度の解釈方法を指定します。

    val createAnchorResult = geospatial.createAnchorOnSurface(
        latitude,
        longitude,
        altitude,
        Quaternion.Identity,
        GeospatialSurface.TERRAIN,
    )

    GeospatialSurface.ROOFTOP を使用する場合、建物上に配置されていないときの高度は、デフォルトで地形の高度になります。

次に、作成呼び出しの結果を確認します。

when (createAnchorResult) {
    is AnchorCreateSuccess -> {
        // Use anchorCreateResult.anchor to render content at the result.
    }

    else -> {
        // Anchor create failed.
        // See AnchorCreateResult for possible failure reasons.
    }
}

最後に、アンカーを使用して 3D コンテンツを配置します。

Compose XR

Subspace(FollowTarget.anchor(anchorCreateResult.anchor)) {
    SpatialPanel {
        GeospatialContent()
    }
}

SceneCore

val anchorSpace = AnchorSpace.create(session, anchorCreateResult.anchor)
val contentEntity = createGeospatialContentEntity(context, session)
anchorSpace.addChild(contentEntity)