執行 hit-test,判斷場景中 3D 物件的正確位置。正確放置 AR 內容可確保 AR 內容以適當的 (透明) 大小顯示。
命中搜尋結果類型
命中測試可以產生四種不同的命中結果,如下表所示。
命中搜尋結果類型 | 說明 | 方向 | 用途 | 方法呼叫 |
---|---|---|---|---|
厚度 (DepthPoint ) |
使用整個場景的深度資訊,判斷點的正確深度和方向 | 垂直 3D 表面 | 將虛擬物體放在任意表面上 (而不只是地板和牆壁) |
您必須啟用 ArDepthMode ,這項功能才能正常運作。Frame.hitTest(…) ,請在退貨清單中尋找 DepthPoint
|
Plane |
根據水平和/或垂直表面,決定點的正確深度和方向 | 垂直於 3D 表面 | 使用飛機的完整幾何圖形將物體置於平面 (地板或牆壁) 上。需要立即修正比例。深度命中測試的備用方案 |
Frame.hitTest(…) ,查看退貨清單中是否有 Plane
|
地圖項目點 (Point ) |
仰賴使用者輕觸點周圍的視覺功能,決定點的正確位置和方向 | 垂直 3D 表面 | 將物體放在任意表面上 (而不只是地板和牆壁) |
Frame.hitTest(…) ,查看退貨清單中是否有 Point
|
即時刊登位置 (InstantPlacementPoint ) |
使用螢幕空間放置內容。一開始會使用應用程式提供的預估深度。雖然可以立即運作,但一旦 ARCore 能夠判斷實際場景幾何形狀,姿勢和實際深度就會改變。 | + Y 指向上,與重力相反 | 使用平面 (地板或牆壁) 的完整幾何圖形,將物件放置在平面上,此時快速放置至關鍵,且體驗可容許未知的初始深度和比例 |
Frame.hitTestInstantPlacement(float, float, float)
|
執行標準命中測試
呼叫 Frame.hitTest()
執行命中測試,使用 TapHelper
公用程式從 AR 檢視畫面取得 MotionEvent
。
MotionEvent tap = tapHelper.poll();
if (tap == null) {
return;
}
if (usingInstantPlacement) {
// When using Instant Placement, the value in APPROXIMATE_DISTANCE_METERS will determine
// how far away the anchor will be placed, relative to the camera's view.
List<HitResult> hitResultList =
frame.hitTestInstantPlacement(tap.getX(), tap.getY(), APPROXIMATE_DISTANCE_METERS);
// Hit-test results using Instant Placement will only have one result of type
// InstantPlacementResult.
} else {
List<HitResult> hitResultList = frame.hitTest(tap);
// TODO: Filter hitResultList to find a hit result of interest.
}
val tap = tapHelper.poll() ?: return
val hitResultList =
if (usingInstantPlacement) {
// When using Instant Placement, the value in APPROXIMATE_DISTANCE_METERS will determine
// how far away the anchor will be placed, relative to the camera's view.
frame.hitTestInstantPlacement(tap.x, tap.y, APPROXIMATE_DISTANCE_METERS)
// Hit-test results using Instant Placement will only have one result of type
// InstantPlacementResult.
} else {
frame.hitTest(tap)
}
根據感興趣的類型篩選命中結果。舉例來說,如果您想專注於 DepthPoint
:
// Returned hit-test results are sorted by increasing distance from the camera or virtual ray's
// origin.
// The first hit result is often the most relevant when responding to user input.
for (HitResult hit : hitResultList) {
Trackable trackable = hit.getTrackable();
if (trackable instanceof DepthPoint) { // Replace with any type of trackable type
// Do something with this hit result. For example, create an anchor at this point of
// interest.
Anchor anchor = hit.createAnchor();
// TODO: Use this anchor in your AR experience.
break;
}
}
// Returned hit-test results are sorted by increasing distance from the camera or virtual ray's
// origin.
// The first hit result is often the most relevant when responding to user input.
val firstHitResult =
hitResultList.firstOrNull { hit ->
when (val trackable = hit.trackable!!) {
is DepthPoint -> true // Replace with any type of trackable type
else -> false
}
}
if (firstHitResult != null) {
// Do something with this hit result. For example, create an anchor at this point of interest.
val anchor = firstHitResult.createAnchor()
// TODO: Use this anchor in your AR experience.
}
使用任意射線和方向,進行命中測試
命中測試通常會視為裝置或裝置相機的射線,但您可以使用 Frame.hitTest(float[], int, float[], int)
,在世界空間座標 (而非螢幕空間點) 中的任意陽光進行命中測試。
根據命中結果建立錨點
取得命中結果後,即可使用其姿勢做為輸入內容,在場景中放置 AR 內容。使用 HitResult.createAnchor()
建立新的 Anchor
,確保內容附加至命中結果的基礎 Trackable
。舉例來說,當飛機命中結果時,錨點會保持與偵測到的飛機保持連接,因此看起來是真實世界的一部分。
後續步驟
- 查看 GitHub 上的
hello_ar_java
和hello_ar_kotlin
範例應用程式。