ARKit從入門到精通(2)--顯示覆雜模型(Swift實現)

上部分(juejin.im/post/5d1897…)咱們在Xcode顯示了一個最簡單的模型(cube),那麼本部分主要實如今Xcode導入製做好的3D模型,使用ARKit在現實環境中顯示出來。node

效果預覽:


3D模型資源:git

https://pan.baidu.com/s/1Lrave2Km_DRims84yI8jmA 密碼:4769
github

原項目工程:swift

https://pan.baidu.com/s/12hAAC_EuTBvqIqz7Iwonxw 密碼:5tm0
bash

本部分的教程直接在這個項目基礎上進行開發。
微信

Step 1: 開發前準備

SceneKit支持兩種格式:SceneKit Scene (.scn)和Digital Asset Exchange (.dae)。app

打開Xcode導入剛剛下載好的項目並Build:ide


Step 2: 顯示單個3D物體

在ViewController類中插入如下方法:
post

func addPaperPlane(x: Float = 0, y: Float = 0, z: Float = -0.5) {
    guard let paperPlaneScene = SCNScene(named: "paperPlane.scn"), let paperPlaneNode = paperPlaneScene.rootNode.childNode(withName: "paperPlane", recursively: true) else { return }
    paperPlaneNode.position = SCNVector3(x, y, z)
    sceneView.scene.rootNode.addChildNode(paperPlaneNode)
}複製代碼

上面的代碼中,咱們首先使用paperPlane.scn初始化SCNScene對象。測試

接下來,咱們初始化打開一個具備paperPlane節點名稱的SCNNode對象。將遞歸參數設置爲true。

初始化節點以後,咱們將paperPlaneNode的位置設置爲x、y和z參數。默認位置是零向量。將z的默認值設置爲-0.5,表示對象位於攝像機前面。

最後,paperPlaneNode添加到sceneView的根節點。

在viewDidLoad()方法中調用addPaperPlane(x:y:z:)方法:

override func viewDidLoad() {
    super.viewDidLoad()
    addPaperPlane()
}複製代碼

接下來點擊運行。你會看到一架白紙飛機,效果以下圖:


運行測試會發現模型有些突兀,這是由於沒有加入Light,接下來實如今場景中加入光源。

Step 3: 添加光源

在ViewController類中,添加如下方法:

func configureLighting() {
    sceneView.autoenablesDefaultLighting = true
    sceneView.automaticallyUpdatesLighting = true
}複製代碼

建立一個configureLighting()方法。在方法內部,咱們將sceneView的autoenablesDefaultLighting屬性設置爲true,SceneKit會自動向場景添加燈光。

接下來,將sceneView的automaticallyUpdatesLighting屬性也設置爲true,視圖自動建立一個或多個SCNLight對象,將它們添加到場景中,並更新它們的屬性。若是想直接控制SceneKit場景中的全部照明,則須要將該值設置爲false。

在viewDidLoad()方法中調用configureLighting()方法:

override func viewDidLoad() {
    super.viewDidLoad()
    configureLighting()
    addPaperPlane()
}複製代碼

再次運行,會發現和第一次徹底不一樣的效果:


Step 4: 顯示模型(車)

對於包含多個nodes的3D模型(好比文件中的小車模型),咱們有不一樣於單個node模型(好比上面的飛機)的處理方法。


打開ViewController.swift文件,在addPaperPlane(x:y:z:)方法下插入如下代碼:

func addCar(x: Float = 0, y: Float = 0, z: Float = -0.5) {
    guard let carScene = SCNScene(named: "car.dae") else { return }
    let carNode = SCNNode()
    let carSceneChildNodes = carScene.rootNode.childNodes
        
    for childNode in carSceneChildNodes {
        carNode.addChildNode(childNode)
    }
        
    carNode.position = SCNVector3(x, y, z)
    carNode.scale = SCNVector3(0.5, 0.5, 0.5)
    sceneView.scene.rootNode.addChildNode(carNode)
}
複製代碼

如今註釋掉addPaperPlane()方法,並在viewDidLoad()方法中調用addCar()方法:

override func viewDidLoad() {
    super.viewDidLoad()
    configureLighting()
    //addPaperPlane()
    addCar()
}複製代碼

接下來點擊運行,效果以下圖:


完整項目連接:https://github.com/appcoda/ARKit3DDemo

參考資料:https://www.appcoda.com/arkit-3d-object/


------AR Portal(AR開發者社區)整理

關注微信公衆號(AR開發者交流社區,提供AR開發乾貨,推進AR內容發展):AR開發者社區

相關文章
相關標籤/搜索