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

1
回复
211
查看
打印 上一主题 下一主题
[ 复制链接 ]
排名
2299
昨日变化

31

主题

252

帖子

1470

积分

Rank: 9Rank: 9Rank: 9

UID
156756
好友
11
蛮牛币
1298
威望
0
注册时间
2016-7-13
在线时间
495 小时
最后登录
2019-10-14

专栏作家

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册帐号

x
本帖最后由 geekli 于 2019-10-9 20:05 编辑

上部分(ARKit从入门到精通(1)--显示Cube(原生方法实现))我们在Xcode显示了一个最简单的模型(cube),那么本部分主要实现在Xcode导入制作好的3D模型,使用ARKit在现实环境中显示出来。

效果预览:

3D模型资源:
https://pan.baidu.com/s/1Lrave2Km_DRims84yI8jmA  密码:4769
原项目工程:
https://pan.baidu.com/s/12hAAC_EuTBvqIqz7Iwonxw  密码:5tm0

本部分的教程直接在这个项目基础上进行开发。

Step 1: 开发前准备

SceneKit支持两种格式:SceneKit Scene (.scn)和Digital Asset Exchange (.dae)。Apple 官方对SceneKit对的解释是:
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’s Documentation

打开Xcode导入刚刚下载好的项目并Build:


Step 2: 显示单个3D物体

在ViewController类中插入以下方法:

[AppleScript] 纯文本查看 复制代码
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:)方法:

[AppleScript] 纯文本查看 复制代码
override func viewDidLoad() {
    super.viewDidLoad()
    addPaperPlane()
}


接下来点击运行。你会看到一架白纸飞机,效果如下图:


运行测试会发现模型有些突兀,这是因为没有加入Light,接下来实现在场景中加入光源。

Step 3: 添加光源

在ViewController类中,添加以下方法:

[AppleScript] 纯文本查看 复制代码
func configureLighting() {
    sceneView.autoenablesDefaultLighting = true
    sceneView.automaticallyUpdatesLighting = true
}


创建一个configureLighting()方法。在方法内部,我们将sceneView的autoenablesDefaultLighting属性设置为true,SceneKit会自动向场景添加灯光。

接下来,将sceneView的automaticallyUpdatesLighting属性也设置为true,视图自动创建一个或多个SCNLight对象,将它们添加到场景中,并更新它们的属性。如果想直接控制SceneKit场景中的所有照明,则需要将该值设置为false。

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

[AppleScript] 纯文本查看 复制代码
override func viewDidLoad() {
    super.viewDidLoad()
    configureLighting()
    addPaperPlane()
}


再次运行,会发现和第一次完全不同的效果:


Step 4: 显示模型(车)
对于包含多个nodes的3D模型(比如文件中的小车模型),我们有不同于单个node模型(比如上面的飞机)的处理方法。


打开ViewController.swift文件,在addPaperPlane(x:y:z:)方法下插入以下代码:
[AppleScript] 纯文本查看 复制代码
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()方法:
[AppleScript] 纯文本查看 复制代码
override func viewDidLoad() {
    super.viewDidLoad()
    configureLighting()
    //addPaperPlane()
    addCar()
}


接下来点击运行,效果如下图:





完整项目链接:
https://github.com/appcoda/ARKit3DDemo
参考资料:
https://www.appcoda.com/arkit-3d-object/


------AR Portal(AR开发者社区)整理
关注微信公众:AR开发者社区
3偶尔光临
179/300
排名
64937
昨日变化

0

主题

102

帖子

179

积分

Rank: 3Rank: 3Rank: 3

UID
143972
好友
0
蛮牛币
108
威望
0
注册时间
2016-3-30
在线时间
75 小时
最后登录
2019-10-14
感谢分享~~~~~~
您需要登录后才可以回帖 登录 | 注册帐号

本版积分规则