更新:作爲在IOS 11.3的(又名「ARKit 1.5」),有是添加ARAnchor
到會話(然後關聯通過ARSCNViewDelegate
回調SceneKit內容與它),只是把內容放在之間的差SceneKit空間。
當您爲會話添加錨點時,您告訴ARKit世界空間中的某個點與您的應用程序相關。然後,ARKit可以做一些額外的工作,以確保其世界座標空間與現實世界精確對齊,至少在該點附近。因此,如果您想讓虛擬內容顯示爲「附加」到某個真實世界的興趣點上,例如將對象放置在桌子或牆上,則由於跟蹤世界,您應該看到更少的「漂移」如果您給該對象一個定位點,而不是將其放置在SceneKit空間中,則該定位點不準確。如果該對象從一個靜態位置移動到另一個靜態位置,則需要刪除原始錨點並在之後的新位置添加一個錨點。
此外,在iOS 11.3中,您可以將opt in設置爲「relocalization」,這個過程可以幫助ARKit在中斷後恢復會話(通過電話,切換應用等)。會議仍然有效,但它試圖弄清楚如何映射你以前的位置到現在的位置,這可能會導致重定位成功後錨點的世界空間位置發生變化。 (另一方面,如果你只是讓空間入侵者漂浮在空中,那麼完美匹配的世界空間就不那麼重要,因此你不會真的看到基於錨和非錨的非常不同的區別 - 基於錨定的定位。)
請參閱Apple的Handling 3D Interaction and UI Controls in Augmented Reality文章/示例代碼中的「使用錨點提高虛擬對象周圍的跟蹤質量」。
該答案的其餘部分與iOS 11.0-11.2的歷史相關。5,並解釋某些方面,所以下面我將離開它...
首先使用ARAnchor
考慮不 SceneKit。
如果您使用ARSKView
,你需要一種方法來參考位置/方位三維(真實世界)的空間,因爲SpriteKit不是3D。您需要ARAnchor
來跟蹤3D中的位置,以便它們可以映射到2D中。
如果你使用Metal(或GL,出於某種奇怪的原因)構建你自己的引擎......這不是一個3D場景描述API--它是一個GPU編程API--所以它並沒有一個概念的世界空間。您可以使用ARAnchor
作爲ARKit的世界空間概念和您構建的任何東西之間的橋樑。
因此,在某些情況下,你需要ARAnchor
因爲這是指3D位置的唯一方法。 (當然,如果你使用平面檢測,你需要ARPlaneAnchor
因爲ARKit實際上搬完相對於場景的空間,因爲它改進了的地方平面是估計。)
隨着ARSCNView
,SceneKit已經有一個三維世界座標空間,ARKit將所有的空間匹配到ARKit映射出來的實際空間。所以,對於一個float4x4
變換描述了在世界空間中的位置(和方向等),您可以:
- 創建
ARAnchor
,將其添加到會話,並ARSCNViewDelegate
回調響應提供SceneKit內容ARKit將添加並定位在場景中的每個錨點。
- 創建一個
SCNNode
,設置它的simdTransform
,並將其添加爲場景的rootNode
的子節點。
只要你有一個跑步ARSession
,這兩種方法之間沒有區別 - 他們是等同的方式來說同樣的事情。所以如果你喜歡以SceneKit的方式做事,那沒什麼問題。 (你甚至可以使用SCNVector3
和SCNMatrix4
,而不是SIMD類型,如果你想要的,但你必須來回轉換,如果你也ARKit的API獲得SIMD類型。)
的一次,這些方法不同的是會話重置。如果世界追蹤失敗,您將恢復中斷的會話,並且/或者您再次開始會話,則「世界空間」可能不再與現實世界一致,就像您將內容放入場景時一樣。
在這種情況下,您可以讓ARKit從會話中刪除錨點 - 請參閱run(_:options:)
方法和ARSession.RunOptions
。 (是的,所有這些,因爲在這一點上你不能相信他們中的任何一個是有效的。)如果你使用錨和委託回調在場景中放置了內容,ARKit將會把所有的內容都燒掉。 (您可以獲得代表回調,它將被刪除。)如果您使用SceneKit API放置了內容,它將停留在場景中(但很可能是錯誤的地方)。
那麼,使用哪種類型取決於你想如何處理會話失敗和中斷(並且在這之外沒有真正的區別)。
所以原因:1)ARNode適用於非SceneKit引擎(SpriteKit,金屬等),對於SceneKit它是相同的(因爲ARKit派生自SceneKit並且具有相同的世界座標),2)如果跟蹤失敗,ARKit可以自動移除所有ARAnchor(並因此關聯的節點),但是SceneKit不會。正確? –
@LimThyeChean Yup。 – rickster
@rickster感謝您的解釋!這節省了我很多時間。 – Mencls