Геопространственные привязки — это тип привязки , позволяющий размещать 3D-контент в реальном мире.
Типы геопространственных привязок
Существует три типа геопространственных привязок, каждый из которых по-разному обрабатывает высоту:
Якоря WGS84 :
Якоря WGS84 позволяют размещать 3D-контент на любой заданной широте, долготе и высоте.Местные якоря :
Привязки к местности позволяют размещать контент, используя только широту и долготу, а также высоту относительно местности в этой позиции. Высота определяется относительно земли или пола, как известно VPS .Анкеры на крыше :
Привязки на крыше позволяют размещать контент, используя только широту и долготу, а также высоту относительно крыши здания в этом положении. Высота определяется относительно вершины здания, известной как Streetscape Geometry . По умолчанию используется высота местности, если она не размещена на здании.
WGS84 | Местность | Крыша | |
---|---|---|---|
Горизонтальное положение | Широта, Долгота | Широта, Долгота | Широта, Долгота |
Вертикальное положение | Относительно высоты WGS84 | Относительно уровня местности, определенного Google Maps | Относительно уровня крыши, определенного с помощью Google Maps. |
Требуется разрешение на сервере? | Нет | Да | Да |
Предварительные условия
Прежде чем продолжить, убедитесь, что вы включили Geospatial API .
Разместите геопространственные привязки
У каждого типа привязки есть специальные API для их создания; дополнительную информацию см. в разделе «Типы геопространственных привязок» .
Создайте якорь на основе хит-теста
Вы также можете создать геопространственную привязку на основе результатов проверки попадания . Используйте Pose из теста попадания и преобразуйте его в GeospatialPose
. Используйте его для размещения любого из трех описанных типов якорей.
Получите геопространственную позу из позы AR
AREarthManager.Convert(Pose)
предоставляет дополнительный способ определения широты и долготы путем преобразования позы AR в геопространственную позу.
Получите позу AR из геопространственной позы
AREarthManager.Convert(GeospatialPose)
преобразует заданное Землей горизонтальное положение, высоту и вращение кватерниона относительно системы координат восток-вверх-юг в AR-позу относительно мировой координаты GL.
Выберите, какой метод подходит для вашего случая использования
Каждый метод создания якоря имеет связанные с ним компромиссы, о которых следует помнить:
- При использовании Streetscape Geometry используйте проверку попадания, чтобы прикрепить контент к зданию.
- Предпочитайте якоря Terrain или Rooftop, а не якоря WGS84, поскольку они используют значения высоты, определенные Google Maps.
Определить широту и долготу места
Вычислить широту и долготу местоположения можно тремя способами:
- Используйте Geospatial Creator , чтобы просматривать и дополнять мир трехмерным контентом без необходимости физического посещения определенного места. Это позволяет визуально размещать иммерсивный 3D-контент с помощью карт Google в редакторе Unity. Широта, долгота, поворот и высота контента будут рассчитаны автоматически.
- Используйте Карты Google
- Используйте Google Планета Земля. Обратите внимание, что получение этих координат с помощью Google Earth, в отличие от Google Maps, даст вам погрешность до нескольких метров.
- Перейти к физическому местоположению
Используйте Карты Google
Чтобы получить широту и долготу местоположения с помощью Google Maps:
Откройте Карты Google на настольном компьютере.
Перейдите в «Слои» > «Еще» .
Измените тип карты на «Спутник» и снимите флажок « Вид глобуса» в левом нижнем углу экрана.
Это позволит использовать 2D-перспективу и устранить возможные ошибки, которые могут возникнуть при просмотре в 3D-виде под углом.
На карте щелкните правой кнопкой мыши местоположение и выберите долготу/широту, чтобы скопировать его в буфер обмена.
Используйте Google Планета Земля
Вы можете рассчитать широту и долготу местоположения с помощью Google Планета Земля, щелкнув местоположение в пользовательском интерфейсе и прочитав данные из сведений о метке.
Чтобы получить широту и долготу местоположения с помощью Google Earth:
Откройте Google Планета Земля на настольном компьютере.
Перейдите в гамбургер-меню и выберите Стиль карты .
Выключите переключатель «3D-здания» .
Когда переключатель «3D-здания» выключен, щелкните значок булавки. чтобы добавить метку в выбранном месте.
Укажите проект, в котором будет храниться метка, и нажмите «Сохранить» .
В поле Название метки введите имя метки.
Нажмите стрелку назад на панели проекта и выберите Меню дополнительных действий .
В меню выберите «Экспортировать как файл KML» .
Файл KLM сообщает широту, долготу и высоту метки в теге <coordinates>
, разделенные запятыми, следующим образом:
<coordinates>-122.0755182435043,37.41347299422944,7.420342565583832</coordinates>
Не используйте широту и долготу из тегов <LookAt>
, которые определяют положение камеры, а не местоположение.
Перейти к физическому местоположению
Вы можете рассчитать высоту места, физически придя туда и проведя местные наблюдения.
Получить кватернион вращения
GeospatialPose.EunRotation
извлекает ориентацию из геопространственной позы и выводит кватернион, который представляет матрицу вращения, преобразующую вектор из цели в систему координат восток-север (EUN). X+ указывает на восток, Y+ указывает вверх вдали от гравитации, а Z+ указывает на север.
Якоря WGS84
Якорь WGS84 — это тип якоря , который позволяет размещать 3D-контент на любой заданной широте, долготе и высоте. Он опирается на позу и ориентацию для размещения в реальном мире. Позиция состоит из широты, долготы и высоты, которые указаны в системе координат WGS84 . Ориентация состоит из вращения кватернионов.
Высота указывается в метрах над эталонным эллипсоидом WGS84, так что уровень земли не равен нулю. Ваше приложение отвечает за предоставление этих координат для каждой созданной привязки.
Разместите якорь WGS84 в реальном мире.
Определить высоту места
Есть несколько способов определить высоту места для установки якорей:
- Если привязка физически находится рядом с пользователем, вы можете использовать высоту, аналогичную высоте устройства пользователя.
- Получив широту и долготу, используйте Elevation API , чтобы получить высоту на основе спецификации EGM96 . Необходимо преобразовать высоту Maps API EGM96 в WGS84 для сравнения с высотой
GeospatialPose
. См. GeoidEval , который имеет как командную строку, так и интерфейс HTML. API Карт сообщает широту и долготу в соответствии со спецификацией WGS84. - Вы можете получить широту, долготу и высоту местоположения из Google Earth . Это даст вам погрешность до нескольких метров. Используйте широту, долготу и высоту из тегов
<coordinates>
, а не тегов<LookAt>
в файле KML. - Если существующая якорь находится рядом и вы не находитесь на крутом склоне, вы можете использовать высоту из
GeospatialPose
камеры, не используя другой источник, например Maps API.
Создайте якорь
Получив кватернион широты, долготы, высоты и вращения, используйте ARAnchorManagerExtensions.AddAnchor()
, чтобы привязать контент к указанным вами географическим координатам.
if (earthTrackingState == TrackingState.Tracking)
{
var anchor =
AnchorManager.AddAnchor(
latitude,
longitude,
altitude,
quaternion);
var anchoredAsset = Instantiate(GeospatialAssetPrefab, anchor.transform);
}
Якоря местности
Якорь местности — это тип якоря , который позволяет размещать объекты AR, используя только широту и долготу, используя информацию от VPS для определения точной высоты над землей.
Вместо ввода желаемой высоты вы указываете высоту над местностью. Когда это значение равно нулю, якорь будет находиться на одном уровне с местностью.
Установите режим поиска плоскости
Поиск плоскости не является обязательным и не требует использования якорей. Обратите внимание, что используются только горизонтальные плоскости. Горизонтальные плоскости помогут динамическому выравниванию якорей местности на земле.
Обратите внимание, что на привязки ландшафта влияют параметры Horizontal
и Horizontal | Vertical
Используйте раскрывающееся меню «Режим обнаружения» , чтобы установить режим обнаружения:
Создайте привязку Terrain с помощью нового API Async.
Чтобы создать и разместить привязку Terrain, вызовите ARAnchorManagerExtensions.resolveAnchorOnTerrainAsync()
.
Якорь не будет готов сразу и его необходимо разрешить. Как только проблема будет решена, она будет доступна в ResolveAnchorOnTerrainPromise
.
public GameObject TerrainAnchorPrefab;
public void Update()
{
ResolveAnchorOnTerrainPromise terrainPromise =
AnchorManager.ResolveAnchorOnTerrainAsync(
latitude, longitude, altitudeAboveTerrain, eunRotation);
// The anchor will need to be resolved.
StartCoroutine(CheckTerrainPromise(terrainPromise));
}
private IEnumerator CheckTerrainPromise(ResolveAnchorOnTerrainPromise promise)
{
yield return promise;
var result = promise.Result;
if (result.TerrainAnchorState == TerrainAnchorState.Success &&
result.Anchor != null)
{
// resolving anchor succeeded
GameObject anchorGO = Instantiate(TerrainAnchorPrefab,
result.Anchor.gameObject.transform);
anchorGO.transform.parent = result.Anchor.gameObject.transform;
}
else
{
// resolving anchor failed
}
yield break;
}
Проверьте состояние обещания
Промис будет иметь связанный с ним PromiseState
.
Состояние | Описание |
---|---|
Pending | Операция еще предстоит. |
Done | Операция завершена, результат доступен. |
Cancelled | Операция отменена. |
Проверьте состояние привязки Terrain в результате Promise.
TerrainAnchorState
принадлежит асинхронной операции и является частью конечного результата Promise.
switch (result.TerrainAnchorState)
{
case TerrainAnchorState.Success:
// Anchor has successfully resolved
break;
case TerrainAnchorState.ErrorUnsupportedLocation:
// The requested anchor is in a location that isn't supported by the Geospatial API.
break;
case TerrainAnchorState.ErrorNotAuthorized:
// An error occurred while authorizing your app with the ARCore API. See
// https://developers.google.com/ar/reference/unity-arf/namespace/Google/XR/ARCoreExtensions#terrainanchorstate_errornotauthorized
// for troubleshooting steps.
break;
case TerrainAnchorState.ErrorInternal:
// The Terrain anchor could not be resolved due to an internal error.
break;
default:
break;
}
Анкеры на крыше
Якоря на крыше представляют собой разновидность якоря и очень похожи на якоря Terrain, описанные выше. Разница в том, что вы указываете высоту над крышей, а не над местностью.
Создайте якорь на крыше с помощью нового API Async.
Якорь не будет готов сразу и его необходимо разрешить.
Чтобы создать и разместить привязку на крыше, вызовите ARAnchorManagerExtensions.resolveAnchorOnRooftopAsync()
. Как и в случае с якорями Terrain, вы также получите доступ к PromiseState
обещания. Затем вы можете проверить результат Promise, чтобы получить доступ к RooftopAnchorState
.
public GameObject RooftopAnchorPrefab;
public void Update()
{
ResolveAnchorOnRooftopPromise rooftopPromise =
AnchorManager.ResolveAnchorOnRooftopAsync(
latitude, longitude, altitudeAboveRooftop, eunRotation);
// The anchor will need to be resolved.
StartCoroutine(CheckRooftopPromise(rooftopPromise));
}
private IEnumerator CheckRooftopPromise(ResolveAnchorOnTerrainPromise promise)
{
yield return promise;
var result = promise.Result;
if (result.RooftopAnchorState == RooftopAnchorState.Success &&
result.Anchor != null)
{
// resolving anchor succeeded
GameObject anchorGO = Instantiate(RooftopAnchorPrefab,
result.Anchor.gameObject.transform);
anchorGO.transform.parent = result.Anchor.gameObject.transform;
}
else
{
// resolving anchor failed
}
yield break;
}
Проверьте состояние обещания
Промис будет иметь связанный с ним PromiseState
, см. таблицу выше.
Проверьте состояние привязки на крыше результата Promise.
RooftopAnchorState
принадлежит асинхронной операции и является частью конечного результата Promise.
switch (result.RooftopAnchorState)
{
case TerrainAnchorState.Success:
// Anchor has successfully resolved
break;
case RooftopAnchorState.ErrorUnsupportedLocation:
// The requested anchor is in a location that isn't supported by the Geospatial API.
break;
case RooftopAnchorState.ErrorNotAuthorized:
// An error occurred while authorizing your app with the ARCore API. See
// https://developers.google.com/ar/reference/unity-arf/namespace/Google/XR/ARCoreExtensions#terrainanchorstate_errornotauthorized
// for troubleshooting steps.
break;
case RooftopAnchorState.ErrorInternal:
// The Rooftop anchor could not be resolved due to an internal error.
break;
default:
break;
}
Что дальше
- Убедитесь, что вы понимаете квоту использования Geospatial API .