2017-07-19 59 views
3

我正在试验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) 
    } 

问题是有时它找不到任何锚,然后我不知道该怎么做。当它发现一些锚点时,它会随机放在我身后,而不是放在我面前,但在我身后。我不知道为什么,因为永远不要打开相机,因此找不到任何锚点。

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

回答

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方法,这点永远是在镜头前。

不要忘记从0使用1.0坐标系CGPoint在hitTest method

在规格化图像A点的坐标空间。 (点(0,0) 表示图像的左上角,点(1,1) 代表右下角。)

如果要放置对象各10米,您可以保存相机位置(在session(_:didUpdate:)方法中)并检查x+z坐标是否已更改得足够远,以放置新对象。

注:

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

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

感谢您的解释。我有一些疑问。在您的示例代码中进行碰撞测试的要点arcRandom应该是0到1之间的某个数字,您说这样的话总是在摄像机前面?然后用x + z坐标来查看用户是否移动了足够。我需要什么坐标来比较这些?那是session.currentFrame?.camera.transform x和z吗? – user1007522

+1

@ user1007522是的,来自功能参数的'frame:ARFrame'总是在摄像头前面。要比较距离,请使用'cameraPosition'(请参阅更新的答案^)。 –