2017-07-19 56 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'(請參閱更新的答案^)。 –