姬長信(Redy)

ARKit从入门到精通(2)–显示复杂模型

**关注微信公众号/uff1aAR开发者社区/uff08国内领先的AR开发者交流学习社区和AR内容平台/uff09** ------------ 上部分/uff08[ARKit从入门到精通(1)--显示Cube/uff08原生方法实现/uff09](http://http://www.cocoachina.com/articles/110123?filter=ios "ARKit从入门到精通(1)--显示Cube/uff08原生方法实现/uff09")/uff09我们在Xcode显示了一个最简单的模型/uff08cube/uff09/uff0c那么本部分主要实现在Xcode导入制作好的3D模型/uff0c使用ARKit在现实环境中显示出来。 ## 效果预览/uff1a ![](https://cocoachina.oss-cn-beijing.aliyuncs.com/article/62084115733009521611.png) 3D模型资源/uff1a https://pan.baidu.com/s/1Lrave2Km_DRims84yI8jmA 密码:4769 原项目工程/uff1a https://pan.baidu.com/s/12hAAC_EuTBvqIqz7Iwonxw 密码:5tm0 本部分的教程直接在这个项目基础上进行开发。 ## Step 1: 开发前准备 SceneKit支持两种格式:SceneKit Scene (.scn)和Digital Asset Exchange (.dae)。Apple 官方对SceneKit对的解释是/uff1a > SceneKit can read scene contents from a file in a supported format, or from an NSData object holding the contents of such a file. Apple/u2019s Documentation 打开Xcode导入刚刚下载好的项目并Build/uff1a ![](https://cocoachina.oss-cn-beijing.aliyuncs.com/article/62084115733010775686.png) ## Step 2: 显示单个3D物体 在ViewController类中插入以下方法: ```swift 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) } ``` 上面的代码中/uff0c我们首先使用paperPlane.scn初始化SCNScene对象。 接下来/uff0c我们初始化打开一个具有paperPlane节点名称的SCNNode对象。将递归参数设置为true。 初始化节点之后/uff0c我们将paperPlaneNode的位置设置为x、y和z参数。默认位置是零向量。将z的默认值设置为-0.5/uff0c表示对象位于摄像机前面。 最后/uff0cpaperPlaneNode添加到sceneView的根节点。 在viewDidLoad()方法中调用addPaperPlane(x:y:z:)方法: ```swift override func viewDidLoad() { super.viewDidLoad() addPaperPlane() } ``` 接下来点击运行。你会看到一架白纸飞机/uff0c效果如下图/uff1a ![](https://cocoachina.oss-cn-beijing.aliyuncs.com/article/62084115733011614534.png) 运行测试会发现模型有些突兀/uff0c这是因为没有加入Light/uff0c接下来实现在场景中加入光源。 ## Step 3: 添加光源 在ViewController类中/uff0c添加以下方法: ```swift func configureLighting() { sceneView.autoenablesDefaultLighting = true sceneView.automaticallyUpdatesLighting = true } ``` 创建一个configureLighting()方法。在方法内部/uff0c我们将sceneView的autoenablesDefaultLighting属性设置为true/uff0cSceneKit会自动向场景添加灯光。 接下来/uff0c将sceneView的automaticallyUpdatesLighting属性也设置为true/uff0c视图自动创建一个或多个SCNLight对象/uff0c将它们添加到场景中/uff0c并更新它们的属性。如果想直接控制SceneKit场景中的所有照明/uff0c则需要将该值设置为false。 在viewDidLoad()方法中调用configureLighting()方法: ```swift override func viewDidLoad() { super.viewDidLoad() configureLighting() addPaperPlane() } ``` 再次运行/uff0c会发现和第一次完全不同的效果/uff1a ![](https://cocoachina.oss-cn-beijing.aliyuncs.com/article/62084115733012338437.png) ## Step 4: 显示模型/uff08车/uff09 对于包含多个nodes的3D模型/uff08比如文件中的小车模型/uff09/uff0c我们有不同于单个node模型/uff08比如上面的飞机/uff09的处理方法。 ![](https://cocoachina.oss-cn-beijing.aliyuncs.com/article/62084115733012732810.png) 打开ViewController.swift文件/uff0c在addPaperPlane(x:y:z:)方法下插入以下代码: ```swift 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()方法/uff0c并在viewDidLoad()方法中调用addCar()方法: ```swift override func viewDidLoad() { super.viewDidLoad() configureLighting() //addPaperPlane() addCar() } ``` 接下来点击运行/uff0c效果如下图/uff1a ![](https://cocoachina.oss-cn-beijing.aliyuncs.com/article/62084115733013338223.png) 完整项目链接/uff1a https://github.com/appcoda/ARKit3DDemo 参考资料/uff1a https://www.appcoda.com/arkit-3d-object/ **------AR Portal/uff08AR开发者社区/uff09整理** **公众号/uff1aAR开发者社区/uff08国内领先的AR开发者交流学习社区和AR内容平台/uff09 **![](https://cocoachina.oss-cn-beijing.aliyuncs.com/article/62084115733013909906.png)