版本記錄
版本號(hào) | 時(shí)間 |
---|---|
V1.0 | 2017.09.27 |
前言
蘋果最近新出的一個(gè)API就是ARKit,是在2017年6月6日,蘋果發(fā)布iOS11系統(tǒng)所新增框架,它能夠幫助我們以最簡單快捷的方式實(shí)現(xiàn)AR技術(shù)功能。接下來幾篇我們就詳細(xì)的對(duì)ARKit框架進(jìn)行詳細(xì)的解析。AR相關(guān)代碼已經(jīng)上傳到Github - 刀客傳奇AR相關(guān)和Building-Your-First-AR-Experience,感興趣的可以看上面幾篇。
1. ARKit框架詳細(xì)解析(一)—— 基本概覽
2. ARKit框架詳細(xì)解析(二)—— 關(guān)于增強(qiáng)現(xiàn)實(shí)和ARKit
Overview - 概覽
上面GitHub中的工程示例,此示例應(yīng)用程序運(yùn)行ARKit世界跟蹤會(huì)話,并顯示在SceneKit視圖中顯示的內(nèi)容。 為了演示平面檢測(cè),應(yīng)用程序只需放置一個(gè)SCNPlane對(duì)象來可視化每個(gè)檢測(cè)到的ARPlaneAnchor 對(duì)象。
Configure and Run the AR Session - 配置和運(yùn)行AR會(huì)話
ARSCNView類是一個(gè)SceneKit視圖,它包含一個(gè)ARSession 對(duì)象,用于管理創(chuàng)建增強(qiáng)現(xiàn)實(shí)(AR)體驗(yàn)所需的運(yùn)動(dòng)跟蹤和圖像處理。 但是,要運(yùn)行會(huì)話,您必須提供會(huì)話配置。
ARWorldTrackingConfiguration類提供高精度的運(yùn)動(dòng)跟蹤功能,可以幫助您將虛擬內(nèi)容放置在真實(shí)世界的表面上。 要啟動(dòng)AR會(huì)話,請(qǐng)使用所需的選項(xiàng)(如平面檢測(cè))創(chuàng)建會(huì)話配置對(duì)象,然后在ARSCNView實(shí)例的會(huì)話對(duì)象上調(diào)用runWithConfiguration:options:方法,具體如下所示:
let configuration = ARWorldTrackingConfiguration()
configuration.planeDetection = .horizontal
sceneView.session.run(configuration)
只有當(dāng)屏幕上顯示的視圖才會(huì)運(yùn)行會(huì)話。
重要提示:如果您的應(yīng)用程序需要ARKit的核心功能,請(qǐng)使用應(yīng)用程序的Info.plist文件部分中的arkit鍵使您的應(yīng)用程序僅在支持ARKit的設(shè)備上可用。 如果AR是應(yīng)用程序的輔助功能,請(qǐng)使用isSupported 屬性來確定是否提供基于AR的功能。
在檢測(cè)到的平面中放置3D內(nèi)容
設(shè)置AR會(huì)話后,可以使用SceneKit
在視圖中放置虛擬內(nèi)容。
當(dāng)啟用平面檢測(cè)時(shí),ARKit會(huì)為每個(gè)檢測(cè)到的平面添加和更新錨點(diǎn)。 默認(rèn)情況下,ARSCNView類為每個(gè)錨點(diǎn)的SceneKit場景添加一個(gè) SCNNode對(duì)象。 您的視圖的委托可以實(shí)現(xiàn)渲染器:renderer:didAddNode:forAnchor:方法來向場景添加內(nèi)容。
相關(guān)代碼如下所示。
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
// Place content only for anchors found by plane detection.
guard let planeAnchor = anchor as? ARPlaneAnchor else { return }
// Create a SceneKit plane to visualize the plane anchor using its position and extent.
let plane = SCNPlane(width: CGFloat(planeAnchor.extent.x), height: CGFloat(planeAnchor.extent.z))
let planeNode = SCNNode(geometry: plane)
planeNode.simdPosition = float3(planeAnchor.center.x, 0, planeAnchor.center.z)
/*
`SCNPlane` is vertically oriented in its local coordinate space, so
rotate the plane to match the horizontal orientation of `ARPlaneAnchor`.
*/
planeNode.eulerAngles.x = -.pi / 2
// Make the plane visualization semitransparent to clearly show real-world placement.
planeNode.opacity = 0.25
/*
Add the plane visualization to the ARKit-managed node so that it tracks
changes in the plane anchor as plane estimation continues.
*/
node.addChildNode(planeNode)
}
如果將內(nèi)容添加為與錨點(diǎn)對(duì)應(yīng)的節(jié)點(diǎn)的子節(jié)點(diǎn),則ARSCNView
類將自動(dòng)移動(dòng)該內(nèi)容,因?yàn)锳RKit會(huì)優(yōu)化其對(duì)平面位置和范圍的估計(jì)。 為了顯示估計(jì)平面的完整范圍,此示例應(yīng)用程序還實(shí)現(xiàn)了renderer:didUpdateNode:forAnchor: 方法,更新SCNPlane 對(duì)象的大小以反映ARKit提供的估計(jì)值,下面看一下示例代碼。
func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
// Update content only for plane anchors and nodes matching the setup created in `renderer(_:didAdd:for:)`.
guard let planeAnchor = anchor as? ARPlaneAnchor,
let planeNode = node.childNodes.first,
let plane = planeNode.geometry as? SCNPlane
else { return }
// Plane estimation may shift the center of a plane relative to its anchor's transform.
planeNode.simdPosition = float3(planeAnchor.center.x, 0, planeAnchor.center.z)
/*
Plane estimation may extend the size of the plane, or combine previously detected
planes into a larger one. In the latter case, `ARSCNView` automatically deletes the
corresponding node for one plane, then calls this method to update the size of
the remaining plane.
*/
plane.width = CGFloat(planeAnchor.extent.x)
plane.height = CGFloat(planeAnchor.extent.z)
}
后記
未完,待續(xù)~~~