ARKit 将模型随机放置在现实世界中

ARKit place models in the real world randomly

我正在尝试使用 ARKit 并尝试在用户周围放置一些模型。所以我想要的是,当应用程序启动时,它只是在用户周围放置一些模型,因此他需要找到它们。

当他移动例如 10 米时,我想再次添加一些随机模型。我以为我可以这样做:

 let cameraTransform = self.sceneView.session.currentFrame?.camera.transform
        let cameraCoordinates = MDLTransform(matrix: cameraTransform!)

        let camX = CGFloat(cameraCoordinates.translation.x)
        let camY = CGFloat(cameraCoordinates.translation.y)
        let cameraPosition = CGPoint(x: camX, y: camY)
        let anchors = self.sceneView.hitTest(cameraPosition, types: [.featurePoint, .estimatedHorizontalPlane])

        if let hit = anchors.first {
            let hitTransform = SCNMatrix4(hit.worldTransform)
            let hitPosition = SCNVector3Make(hitTransform.m41, hitTransform.m42, hitTransform.m43)
            self.sceneView.session.add(anchor: ARAnchor(transform: hit.worldTransform))
            return Coordinate(hitPosition.x, hitPosition.y, hitPosition.z)
        }

        return Coordinate(0, 0, 0)
    }

问题是有时找不到任何锚点,然后我不知道该怎么办。当它找到一些锚点时,它会随机放在我身后,而不是在我面前,而是在我身后。我不知道为什么,因为从不转动相机,所以它找不到任何锚点。

有没有更好的方法在现实世界中放置随机模型?

要做到这一点,您需要使用 session(_:didUpdate:) 委托方法:

func session(_ session: ARSession, didUpdate frame: ARFrame) {
    guard let cameraTransform = session.currentFrame?.camera.transform else { return }
    let cameraPosition = SCNVector3(
        /* At this moment you could be sure, that camera properly oriented in world coordinates */
        cameraTransform.columns.3.x,
        cameraTransform.columns.3.y,
        cameraTransform.columns.3.z
    )
    /* Now you have cameraPosition with x,y,z coordinates and you can calculate distance between those to points */
    let randomPoint = CGPoint(
        /* Here you can make random point for hitTest. */
        x: CGFloat(arc4random()) / CGFloat(UInt32.max),
        y: CGFloat(arc4random()) / CGFloat(UInt32.max)
    )
    guard let testResult = frame.hitTest(randomPoint, types: .featurePoint).first else { return }
    let objectPoint = SCNVector3(
        /* Converting 4x4 matrix into x,y,z point */
        testResult.worldTransform.columns.3.x,
        testResult.worldTransform.columns.3.y,
        testResult.worldTransform.columns.3.z
    )
    /* do whatever you need with this object point */
}

它允许您在相机位置更新时放置对象:

Implement this method if you provide your own display for rendering an AR experience. The provided ARFrame object contains the latest image captured from the device camera, which you can render as a scene background, as well as information about camera parameters and anchor transforms you can use for rendering virtual content on top of the camera image.

这里真的很重要,你是随机选择hitTest方法的点,这个点总是在镜头前。

不要忘记在 hitTest method:

中为 CGPoint 使用 0 到 1.0 坐标系

A point in normalized image coordinate space. (The point (0,0) represents the top left corner of the image, and the point (1,1) represents the bottom right corner.)

如果您想每 10 米放置一个物体,您可以保存相机位置(在 session(_:didUpdate:) 方法中)并检查 x+z 坐标是否已更改足够远,以放置新物体。

注意:

我假设您正在使用世界跟踪会话:

let configuration = ARWorldTrackingSessionConfiguration()
session.run(configuration, options: [.resetTracking, .removeExistingAnchors])