Usar edifícios e terrenos ao seu redor no Unity

As APIs Streetscape Geometry fornecem a geometria de terrenos, edifícios ou outras estruturas em uma cena. A geometria pode ser usada para obstrução, renderização ou posicionamento de conteúdo de RA por meio de APIs de hit-test. Os dados de geometria da paisagem urbana são obtidos com as imagens do Google Street View.

Testar o exemplo

O app de exemplo geoespacial demonstra como conseguir e renderizar geometrias da paisagem urbana.

Configurar a API Geospatial

Para usar a geometria da paisagem urbana, você precisa configurar a API Geospatial no seu projeto. Siga as instruções em Como ativar a API Geospatial para configurar a API Geospatial.

Ativar a geometria da paisagem urbana

A API Geospatial extrai dados da geometria da paisagem urbana quando GeospatialMode é definido como GeospatialMode.Enabled e StreetscapeGeometryMode é definido como StreetscapeGeometryMode.Enabled.

Extrair a geometria da paisagem urbana em uma sessão do ARCore

Adicione um componente ARStreetscapeGeometryManager a um GameObject. Quando as geometrias do Street View são adicionadas, atualizadas ou removidas, o evento ARStreetscapeGeometryManager.StreetscapeGeometriesChanged é acionado.

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;
}

Entenda o ARStreetscapeGeometry

ARStreetscapeGeometry contém informações sobre um edifício:

Criação de LOD 1

O BuildingLOD1 consiste em impressões de edifícios extrudadas para cima até uma parte superior plana. As alturas dos edifícios podem ser imprecisas.

LOD 2 do edifício

BuildingLOD2 terá uma geometria de maior fidelidade. As paredes e os telhados de malha vão se ajustar melhor à forma do edifício. Elementos menores, como chaminés ou aberturas no telhado, ainda podem aparecer fora da malha.

Entenda o Mesh

Mesh é uma malha de polígonos que representa uma reconstrução de superfície da geometria do Streetscape. Consulte Mesh e MeshRenderer. As normais não são calculadas por padrão. Consulte Mesh.RecalculateNormals() para calculá-las.

Anexar conteúdo de RA a um ARStreetscapeGeometry

Use ARAnchorManager.AddAnchor() para criar uma âncora em uma determinada pose perto de vértices em ARStreetscapeGeometry.mesh. Essa âncora vai herdar o estado de rastreamento do ARStreetscapeGeometry pai.

Realize um teste de hit em ARStreetscapeGeometry.

ARRaycastManagerExtensions.RaycastStreetscapeGeometry pode ser usado para fazer testes de hit com a geometria da paisagem urbana. Se houver interseções, XRRaycastHit vai conter informações de pose sobre o local do hit, além de uma referência ao ARStreetscapeGeometry que foi atingido. Essa geometria Streetscape pode ser transmitida para ARAnchorManager.AddAnchor() para criar uma âncora anexada a ela.

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);
  }
}

Ativar a profundidade geoespacial

A Geospatial Depth combina a Streetscape Geometry com a entrada do sensor local para melhorar os dados de profundidade. Quando a API Geospatial Depth está ativada, a profundidade de saída e as imagens de profundidade bruta são modificadas para incluir a geometria da paisagem urbana rasterizada, além da profundidade observada localmente. Isso pode melhorar a precisão das poses usando a profundidade.