1.本部分教程使用的是原生iOS開發,目前不涉及Unity,主要使用SceneKit。
node
2.使用的軟件版本:Xcode 9。swift
3.使用的開發語言版本:Swift 4bash
4.本系列專欄但願經過簡潔的語言與圖片幫助你們更好的理解ARKit開發流程,幫助你們開發出炫酷的AR應用。微信
打開Xcode,點擊File > New > Project…,選擇Single View App,點擊Next建立項目,命名爲ARKitDemo。以下圖操做所示:session
設置SceneKit Viewapp
打開Main.storyboard,將ARKit SceneKit視圖拖放到視圖控制器上。
ide
而後將ARKit SceneKit視圖約束填充整個視圖控制器。測試
鏈接IBOutletui
在ViewController.swift文件的頂部添加一個import語句來導入ARKit:spa
import ARKit複製代碼
而後按住control鍵並從ARKit SceneKit視圖拖拽到ViewController.swift文件。當提示時,命名IBOutlet sceneView。能夠刪除didReceiveMemoryWarning() 方法,目前咱們並不須要它。
配置ARSCNView Session
咱們的AR應用程序是經過攝像頭觀察世界和周圍的環境。因此接下來咱們須要設置Camera:
配置ARKit SceneKit View。在ViewController類中插入如下代碼:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let configuration = ARWorldTrackingConfiguration()
sceneView.session.run(configuration)
}複製代碼
在viewWillAppear(_:)方法中,咱們初始化了一個名爲ARWorldTrackingConfiguration的AR配置。主要用於實現World Tracking功能。
The World Tracking配置跟蹤設備的方向和位置,它還能經過設備的Camera探測真實世界的表面。
設置sceneView’s AR session來運行咱們剛剛初始化的配置。AR session管理視圖內容的運動跟蹤和camera圖像處理。
如今在ViewController中添加另外一個方法:
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
sceneView.session.pause()
}複製代碼
在viewWillDisappear(_:)方法中主要處理:中止tracking和視圖內容的圖像。
Camera 受權
在咱們運行應用程序以前,咱們須要通知用戶咱們將使用他們設備的攝像頭實現加強現實功能。這是iOS 10發佈以來的一個要求。
打開Info.plist。右鍵單擊空白區域並選擇Add row。設置私隱相機使用說明鍵。值能夠設置爲Augmented Reality。以下圖所示:
接下來咱們提早測試下Camera是否能夠順利的調用出來。將測試手機鏈接到Mac上。在Xcode上構建並運行該項目。該應用程序應該會提示你容許攝像頭進入。以下圖所示:
插入如下代碼到你的ViewController類:
func addBox() {
let box = SCNBox(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0)
let boxNode = SCNNode()
boxNode.geometry = box
boxNode.position = SCNVector3(0, 0, -0.2)
let scene = SCNScene()
scene.rootNode.addChildNode(boxNode)
sceneView.scene = scene
}複製代碼
建立一個Box,1 Float = 1 meter。
建立一個node。node表示物體在三維空間中的位置和座標。node自己沒有可見的內容。
給node設置一個形狀(Box)。
設置box的位置。這個位置相對於camera的,右邊是X正,左邊是X負。上面表示Y正,向下表示Y負。向後表示Z正,向前表示Z負。
建立一個scene(SceneKit scene),將box添加到場景中去。
將sceneView的scene設置爲顯示剛剛建立的場景。
override func viewDidLoad() {
super.viewDidLoad()
addBox()
}複製代碼
接下來Build,打開camera,出現白色的box,效果以下圖:
addBox()的方法也能夠這樣寫:
func addBox() {
let box = SCNBox(width: 0.05, height: 0.05, length: 0.05, chamferRadius: 0)
let boxNode = SCNNode()
boxNode.geometry = box
boxNode.position = SCNVector3(0, 0, -0.2)
sceneView.scene.rootNode.addChildNode(boxNode)
}複製代碼
在ViewController.swift文件中插入如下方法:
@objc func didTap(withGestureRecognizer recognizer: UIGestureRecognizer) {
let tapLocation = recognizer.location(in: sceneView)
let hitTestResults = sceneView.hitTest(tapLocation)
guard let node = hitTestResults.first?.node else { return }
node.removeFromParentNode()
}複製代碼
建立了一個didTap(帶有gesturerecognizer:)方法。檢索用戶相對於sceneView的點擊位置,而後t查看是否點擊了任何node。而後從hitTestResults中找到第一個node。若是結果確實包含至少一個node,那麼咱們將從其父節點刪除第一個節點。
在測試刪除對象以前,更新viewDidLoad()方法,添加對addTapGestureToSceneView()方法的調用:
override func viewDidLoad() {
super.viewDidLoad()
addBox()
addTapGestureToSceneView()
}複製代碼
在ViewController類的末尾建立一個extension:
extension float4x4 {
var translation: float3 {
let translation = self.columns.3
return float3(translation.x, translation.y, translation.z)
}
}複製代碼
extension將矩陣轉換爲float3。修改addBox()方法:
func addBox(x: Float = 0, y: Float = 0, z: Float = -0.2) {
let box = SCNBox(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0)
let boxNode = SCNNode()
boxNode.geometry = box
boxNode.position = SCNVector3(x, y, z)
sceneView.scene.rootNode.addChildNode(boxNode)
}複製代碼
修改didTap(使用gesturerecognizer:)方法,在guard let語句內部和return語句以前。添加如下代碼:
let hitTestResultsWithFeaturePoints = sceneView.hitTest(tapLocation, types: .featurePoint)
if let hitTestResultWithFeaturePoints = hitTestResultsWithFeaturePoints.first {
let translation = hitTestResultWithFeaturePoints.worldTransform.translation
addBox(x: translation.x, y: translation.y, z: translation.z)
}複製代碼
接下來實現使用x、y和z在檢測到的點擊時添加一個新的box。didTap(withGestureRecognizer:)方法的代碼以下:
@objc func didTap(withGestureRecognizer recognizer: UIGestureRecognizer) {
let tapLocation = recognizer.location(in: sceneView)
let hitTestResults = sceneView.hitTest(tapLocation)
guard let node = hitTestResults.first?.node else {
let hitTestResultsWithFeaturePoints = sceneView.hitTest(tapLocation, types: .featurePoint)
if let hitTestResultWithFeaturePoints = hitTestResultsWithFeaturePoints.first {
let translation = hitTestResultWithFeaturePoints.worldTransform.translation
addBox(x: translation.x, y: translation.y, z: translation.z)
}
return
}
node.removeFromParentNode()
}複製代碼
運行效果以下圖:
參考連接:https://www.appcoda.com/arkit-introduction-scenekit/
------AR Portal(AR開發者社區)整理
關注微信公衆號(AR開發者交流社區,提供AR開發乾貨,推進AR內容發展):AR開發者社區