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

时间:2017-07-19 14:07:42

标签: ios swift3 arkit

我正在尝试使用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)
    }

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

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

1 个答案:

答案 0 :(得分:3)

为了实现这一目标,您需要使用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 */
}

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

  

如果您提供自己的显示来渲染,请实现此方法   AR体验。提供的ARFrame对象包含最新图像   从设备摄像头捕获,您可以将其渲染为场景   背景,以及有关相机参数和锚点的信息   您可以使用转换来渲染虚拟内容   相机图像。

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

请勿忘记在hitTest method中使用0到1.0的CGPoint坐标系:

  

归一化图像坐标空间中的一个点。 (点(0,0)   代表图像的左上角,以及点(1,1)   代表右下角。)

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

注意:

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

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