确定锚点在当前屏幕中是否可见

Figuring out if Anchor is visible in current screen

我正在使用 ARCore 构建我的 android 应用程序,我允许用户在其中放置锚点。我需要能够检查锚点是否在当前帧中。 知道我该怎么做吗? 谢谢!

如果您使用的是 ARCore,您可能正在进行视锥体剔除,其中您不渲染不在可见范围内的对象 space,这是一种用于阻止您进行 gl 调用的优化渲染场景的 "unviewable" 个元素。

如果在渲染器计算后您可以访问对象,那么您可以使用该值。

执行此操作的另一种方法是抓住相机并获取视图和投影矩阵。然后你可以将锚点坐标投影到二维屏幕坐标上,如果计算出的坐标在屏幕之外(即 x/y 值 > 或 < 屏幕 width/height)。您还必须考虑相机后面的物体(相机前向与从相机到锚点的矢量之间的点积应该为正)。

https://developers.google.com/ar/reference/java/com/google/ar/core/Camera.html.

有一种非常简单的方法可以做到这一点。假设您有一个 AnchorNode 附加到您的锚点。

首先获取节点世界位置:

val worldPosition = node.worldPosition

二、使用场景相机将世界位置转换为屏幕点:

val screenPoint = arFragment.arSceneView.scene.camera.worldToScreenPoint(worldPosition)

现在只需检查该点是否在屏幕尺寸范围内。

我创建了一个基于 camera.worldToScreenPoint(worldPosition) 的方法。所以我可以检查一个位置是否可见:

fun com.google.ar.sceneform.Camera.isWorldPositionVisible(worldPosition: Vector3): Boolean {
    val var2 = com.google.ar.sceneform.math.Matrix()
    com.google.ar.sceneform.math.Matrix.multiply(projectionMatrix, viewMatrix, var2)
    val var5: Float = worldPosition.x
    val var6: Float = worldPosition.y
    val var7: Float = worldPosition.z
    val var8 = var5 * var2.data[3] + var6 * var2.data[7] + var7 * var2.data[11] + 1.0f * var2.data[15]
    if (var8 < 0f) {
        return false
    }
    val var9 = Vector3()
    var9.x = var5 * var2.data[0] + var6 * var2.data[4] + var7 * var2.data[8] + 1.0f * var2.data[12]
    var9.x = var9.x / var8
    if (var9.x !in -1f..1f) {
        return false
    }

    var9.y = var5 * var2.data[1] + var6 * var2.data[5] + var7 * var2.data[9] + 1.0f * var2.data[13]
    var9.y = var9.y / var8
    return var9.y in -1f..1f
}

(我修复了 Anton Stukov 在评论中提到的问题)