Neo địa không gian là một loại neo cho phép bạn đặt nội dung 3D vào thế giới thực.
Các loại neo không gian địa lý
Có ba loại neo Địa không gian, mỗi loại xử lý độ cao theo cách khác nhau:
Mốc WGS84:
Mốc WGS84 cho phép bạn đặt nội dung 3D ở bất kỳ vĩ độ, kinh độ và độ cao nào.Mốc cố định địa hình:
Mốc cố định địa hình cho phép bạn chỉ sử dụng vĩ độ và kinh độ để đặt nội dung với chiều cao tương ứng với địa hình tại vị trí đó. Cao độ được xác định so với mặt đất hoặc sàn nhà theo VPS.Mốc trên mái nhà:
Mốc trên mái nhà cho phép bạn chỉ sử dụng vĩ độ và kinh độ để đặt nội dung với chiều cao tương ứng với mái nhà của một toà nhà ở vị trí đó. Cao độ được xác định tương ứng với đỉnh của một toà nhà theo Hình học cảnh quan đường phố. Giá trị này sẽ mặc định là độ cao của địa hình khi không được đặt trên một toà nhà.
WGS84 | Địa hình | Sân thượng | |
---|---|---|---|
Vị trí ngang | Vĩ độ, Kinh độ | Vĩ độ, Kinh độ | Vĩ độ, Kinh độ |
Vị trí dọc | So với độ cao WGS84 | So với cấp độ địa hình do Google Maps xác định | So với cấp độ mái nhà do Google Maps xác định |
Có cần được máy chủ phân giải không? | Không | Có | Có |
Điều kiện tiên quyết
Hãy nhớ bật API không gian địa lý trước khi tiếp tục.
Đặt neo Không gian địa lý
Mỗi loại neo đều có các API chuyên dụng để tạo; hãy xem phần Các loại neo không gian địa lý để biết thêm thông tin.
Tạo neo từ một lượt kiểm thử nhấn
Bạn cũng có thể tạo một neo Địa không gian từ kết quả kiểm thử lượt nhấn.
Sử dụng tư thế từ kiểm thử lượt nhấn và chuyển đổi tư thế đó thành GeospatialPose
. Sử dụng thuộc tính này để đặt bất kỳ loại neo nào trong số 3 loại được mô tả.
Nhận tư thế không gian địa lý từ tư thế AR
AREarthManager.Convert(Pose)
cung cấp thêm một cách để xác định vĩ độ và kinh độ bằng cách chuyển đổi một Tư thế AR thành Tư thế không gian địa lý.
Lấy tư thế AR từ tư thế không gian địa lý
AREarthManager.Convert(GeospatialPose)
chuyển đổi vị trí ngang, độ cao và phép xoay quaternion do Trái Đất chỉ định theo khung toạ độ đông-lên-nam thành một tư thế AR theo toạ độ thế giới GL.
Chọn phương thức phù hợp với trường hợp sử dụng của bạn
Mỗi phương thức tạo neo đều có những điểm đánh đổi liên quan mà bạn cần lưu ý:
- Khi sử dụng Hình học cảnh quan đường phố, hãy sử dụng tính năng kiểm thử lượt nhấn để đính kèm nội dung vào một toà nhà.
- Ưu tiên sử dụng điểm neo Địa hình hoặc Trên mái nhà hơn điểm neo WGS84 vì các điểm neo này sử dụng giá trị độ cao do Google Maps xác định.
Xác định vĩ độ và kinh độ của một vị trí
Có 3 cách để bạn có thể tính vĩ độ và kinh độ của một vị trí:
- Sử dụng Trình tạo không gian địa lý để xem và bổ sung thế giới bằng nội dung 3D mà không cần phải đến một vị trí thực tế. Điều này cho phép bạn đặt nội dung 3D sống động một cách trực quan bằng cách sử dụng Google Maps trong Trình chỉnh sửa Unity. Hệ thống sẽ tự động tính toán vĩ độ, kinh độ, độ xoay và độ cao của nội dung.
- Sử dụng Google Maps
- Sử dụng Google Earth. Xin lưu ý rằng việc lấy các toạ độ này bằng Google Earth, thay vì Google Maps, sẽ cho bạn sai số lên đến vài mét.
- Chuyển đến vị trí thực tế
Sử dụng Google Maps
Cách lấy vĩ độ và kinh độ của một vị trí bằng Google Maps:
Truy cập vào Google Maps trên máy tính.
Chuyển đến Layers (Lớp) > More (Thêm).
Thay đổi Loại bản đồ thành Vệ tinh và bỏ đánh dấu hộp Chế độ xem hình ảnh địa cầu ở góc dưới cùng bên trái màn hình.
Thao tác này sẽ buộc sử dụng phối cảnh 2D và loại bỏ các lỗi có thể xảy ra từ chế độ xem 3D góc.
Trên bản đồ, hãy nhấp chuột phải vào vị trí rồi chọn kinh độ/vĩ độ để sao chép vị trí đó vào bảng nhớ tạm.
Sử dụng Google Earth
Bạn có thể tính toán vĩ độ và kinh độ của một vị trí trên Google Earth bằng cách nhấp vào một vị trí trong giao diện người dùng và đọc dữ liệu từ thông tin chi tiết về điểm đánh dấu.
Cách lấy vĩ độ và kinh độ của một vị trí bằng Google Earth:
Truy cập vào Google Earth trên máy tính.
Chuyển đến trình đơn dạng bánh hamburger rồi chọn Kiểu bản đồ.
Tắt nút chuyển Tòa nhà 3D.
Sau khi tắt nút chuyển Tòa nhà 3D, hãy nhấp vào biểu tượng ghim để thêm điểm đánh dấu địa điểm tại vị trí đã chọn.
Chỉ định một dự án để chứa dấu vị trí rồi nhấp vào Lưu.
Trong trường Tiêu đề cho dấu vị trí, hãy nhập tên cho dấu vị trí đó.
Nhấp vào mũi tên quay lại trong ngăn dự án rồi chọn trình đơn Thao tác khác.
Chọn Export as KML file (Xuất dưới dạng tệp KML) trong trình đơn.
Tệp KLM báo cáo vĩ độ, kinh độ và độ cao của một điểm đánh dấu trong thẻ <coordinates>
được phân tách bằng dấu phẩy, như sau:
<coordinates>-122.0755182435043,37.41347299422944,7.420342565583832</coordinates>
Không sử dụng vĩ độ và kinh độ từ thẻ <LookAt>
. Các thẻ này chỉ định vị trí của máy ảnh chứ không phải vị trí.
Chuyển đến vị trí thực tế
Bạn có thể tính độ cao của một địa điểm bằng cách đến đó và quan sát tại chỗ.
Lấy quaternion xoay
GeospatialPose.EunRotation
trích xuất hướng từ một Tư thế không gian địa lý và xuất ra một quaternion đại diện cho ma trận xoay biến đổi một vectơ từ mục tiêu đến hệ toạ độ đông-lên-bắc (EUN). X+ chỉ về hướng đông, Y+ chỉ lên trên, ngược với trọng lực và Z+ chỉ về hướng bắc.
Điểm neo WGS84
Neo WGS84 là một loại neo cho phép bạn đặt nội dung 3D ở bất kỳ vĩ độ, kinh độ và độ cao nào. Mô hình này dựa vào một tư thế và hướng để được đặt trong thế giới thực. Vị trí bao gồm vĩ độ, kinh độ và độ cao, được chỉ định trong hệ toạ độ WGS84. Hướng bao gồm một phép xoay quaternion.
Độ cao được báo cáo bằng mét trên hình elip WGS84 tham chiếu, tức là mặt đất không ở mức 0. Ứng dụng của bạn chịu trách nhiệm cung cấp các toạ độ này cho mỗi neo đã tạo.
Đặt neo WGS84 trong thế giới thực
Xác định độ cao của một vị trí
Có một số cách để xác định độ cao của một vị trí để đặt neo:
- Nếu vị trí của điểm neo nằm gần người dùng, bạn có thể sử dụng độ cao tương tự như độ cao của thiết bị của người dùng.
- Sau khi có vĩ độ và kinh độ, hãy sử dụng Elevation API (API Độ cao) để lấy độ cao dựa trên thông số kỹ thuật EGM96. Bạn phải chuyển đổi độ cao EGM96 của API Maps thành WGS84 để so sánh với độ cao
GeospatialPose
. Xem GeoidEval có cả dòng lệnh và giao diện HTML. API Maps báo cáo vĩ độ và kinh độ theo thông số kỹ thuật WGS84 ngay từ đầu. - Bạn có thể lấy vĩ độ, kinh độ và độ cao của một vị trí từ Google Earth. Điều này sẽ mang lại cho bạn một sai số lên đến vài mét. Sử dụng vĩ độ, kinh độ và độ cao từ thẻ
<coordinates>
, không phải thẻ<LookAt>
, trong tệp KML. - Nếu một điểm neo hiện có ở gần và nếu bạn không ở trên một con dốc dựng đứng, thì bạn có thể sử dụng độ cao từ
GeospatialPose
của máy ảnh mà không cần sử dụng nguồn khác, chẳng hạn như API Maps.
Tạo neo
Sau khi bạn có vĩ độ, kinh độ, độ cao và quaternion xoay, hãy sử dụng ARAnchorManagerExtensions.AddAnchor()
để liên kết nội dung với toạ độ địa lý mà bạn chỉ định.
if (earthTrackingState == TrackingState.Tracking)
{
var anchor =
AnchorManager.AddAnchor(
latitude,
longitude,
altitude,
quaternion);
var anchoredAsset = Instantiate(GeospatialAssetPrefab, anchor.transform);
}
Neo địa hình
Điểm neo địa hình là một loại điểm neo cho phép bạn đặt các đối tượng AR chỉ bằng vĩ độ và kinh độ, tận dụng thông tin từ VPS để tìm độ cao chính xác so với mặt đất.
Thay vì nhập độ cao mong muốn, bạn cung cấp độ cao so với địa hình. Khi giá trị này bằng 0, điểm neo sẽ bằng với địa hình.
Đặt chế độ tìm máy bay
Bạn không bắt buộc phải sử dụng tính năng tìm mặt phẳng để sử dụng neo. Xin lưu ý rằng chỉ các mặt phẳng ngang mới được sử dụng. Các mặt phẳng ngang sẽ giúp căn chỉnh linh động các neo địa hình trên mặt đất.
Xin lưu ý rằng các neo địa hình chịu ảnh hưởng của Horizontal
và Horizontal | Vertical
Sử dụng trình đơn thả xuống Chế độ phát hiện để đặt chế độ phát hiện:
Tạo neo Địa hình bằng API không đồng bộ mới
Để tạo và đặt neo Địa hình, hãy gọi ARAnchorManagerExtensions.resolveAnchorOnTerrainAsync()
.
Liên kết sẽ chưa sẵn sàng ngay lập tức và cần được phân giải. Sau khi được giải quyết, tệp này sẽ xuất hiện trong 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;
}
Kiểm tra trạng thái của Lời hứa
Lời hứa sẽ có một PromiseState
được liên kết.
Tiểu bang | Mô tả |
---|---|
Pending |
Thao tác này vẫn đang chờ xử lý. |
Done |
Thao tác đã hoàn tất và kết quả đã có. |
Cancelled |
Thao tác đã bị huỷ. |
Kiểm tra trạng thái neo Địa hình của kết quả Promise
TerrainAnchorState
thuộc về thao tác không đồng bộ và là một phần của kết quả Promise cuối cùng.
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;
}
Neo trên mái nhà
Điểm neo trên mái nhà là một loại điểm neo và rất giống với điểm neo Địa hình ở trên. Điểm khác biệt là bạn sẽ cung cấp độ cao trên mái nhà thay vì độ cao trên địa hình.
Tạo một điểm neo trên mái nhà bằng API không đồng bộ mới
Liên kết sẽ chưa sẵn sàng ngay lập tức và cần được phân giải.
Để tạo và đặt neo trên mái nhà, hãy gọi ARAnchorManagerExtensions.resolveAnchorOnRooftopAsync()
. Tương tự như neo Địa hình, bạn cũng sẽ truy cập vào PromiseState
của Lời hứa. Sau đó, bạn có thể kiểm tra kết quả Promise để truy cập vào 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;
}
Kiểm tra trạng thái của Lời hứa
Lời hứa sẽ có một PromiseState
liên kết, hãy xem bảng ở trên.
Kiểm tra trạng thái neo Rooftop của kết quả Promise
RooftopAnchorState
thuộc về thao tác không đồng bộ và là một phần của kết quả Promise cuối cùng.
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;
}
Bước tiếp theo
- Hãy đảm bảo bạn hiểu rõ hạn mức sử dụng API về không gian địa lý.