在 Unity 中使用周围的建筑物和地形

Streetscape Geometry API 可提供场景中地形、建筑物或其他结构的几何图形。您可以使用该几何图形通过碰撞检测 API 进行遮挡、渲染或放置 AR 内容。街景几何图形数据是通过 Google 街景图像获取的。

试用示例

Geospatial 示例应用演示了如何获取和渲染街景几何图形。

设置 Geospatial API

如需使用街景几何图形,您需要在项目中设置 Geospatial API。 按照启用 Geospatial API 中的说明设置 Geospatial API。

启用街景几何图形

GeospatialMode 设置为 GeospatialMode.EnabledStreetscapeGeometryMode 设置为 StreetscapeGeometryMode.Enabled 时,Geospatial API 会获取街景几何图形数据。

在 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 的引用。此 Streetscape Geometry 可以传递给 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 将 Streetscape Geometry 与本地传感器输入相结合,以增强深度数据。启用 Geospatial Depth 后,输出深度和原始深度图片会被修改,以包含光栅化街景几何图形以及本地观察到的深度。这可能会提高使用深度数据估算姿势的准确性。