iOS - SceneKit显示与交互3D建模(一)

最近公司要求在手机上显示3D模型,并且要获取点击的模型坐标,找了很多相关资料,发现有两种实现方式,一种是集成Unity3D,另一种是使用苹果提供的SceneKit;由于使用Unity3D太麻烦,于是选择使用SceneKit,而且这个是原生的,速度可想而知要比集成U3D后运行要来得快~

SceneKit建立在 OpenGL 的基础上,包含了如光照、模型、材质、摄像机等高级引擎特性。SceneKit实现的内容为节点层次结构树,也被称为场景图。一个场景由一个为场景世界定义一个坐标空间的根节点,以及其他的可视节点组成。SceneKit会在一个视图上展示场景,而这个场景在GPU上�进行有效地渲染每一帧之前,会处理场景�数据图和执行动画。

�接着来来了解下坐标吧,查阅苹果官方文档,可以看到如下这张图片,SceneKit使用的是右手坐标系,默认视图的方向是沿负Z轴方向的。可以简单的记住红色为x轴,绿色为y轴,蓝色为z轴。

坐标

初出茅庐

我们先来创建一个游戏工程

游戏工程

Game Technology选择SceneKit

Paste_Image.png

项目的目录结构如下,比开发APP应用的项目多了一个scnassets文件夹,里面有一个scn后缀的文件,它是xcode能识别的�场景文件。它支持一种后缀为dae的模型文件,我们后续就会用到。

目录结构

运行后如图所示,真是有够炫的,图的下方显示的是当前渲染相关数据,方便我们开发者查看。

�Game Demo

初窥门径

代码从上至下的流程:

  1. 创建一个场景scene,场景本身并不可见,需要添加到sceneView的场景上
  2. 创建一个摄像机节点并设置摆放的位置,所处位置即视角所看的位置,可以联想到眼睛视角
  3. 创建灯光节点设置摆放的位置,灯光可以让需要呈现的物体变得更有质感。
  4. 获取飞机模型,其中的【recursively:YES】意思为是否在子节点中查询。
  5. 设置飞机模型绕着y轴旋转,使用的是SCNAction,用法也很简单。
  6. 获取SCNView,并设置scnView。

牛刀小试

那接下来我们自己也搞一个工程来试试吧

应用工程

在Link Binary With Libraries中引入SceneKit库

引入SceneKit库

在ViewController中导入SceneKit

#import <SceneKit/SceneKit.h>

接下来在桌面上新建一个art文件夹,并加上后缀【.scnassets】,将我们的素材Menchi.dae放进里面,然后把art.scnassets拖进项目中,接下来代码献上

// �初始化一个场景
SCNScene *scene = [SCNScene sceneNamed:@"art.scnassets/Menchi.dae"];

// 取出场景中根结点的第一个结点(目录根结点也就一个子结点,就是我们素材中的Menchi)
SCNNode *node = scene.rootNode.childNodes.firstObject;
// 绕 y轴 一直旋转
SCNAction *action = [SCNAction repeatActionForever:[SCNAction rotateByX:0 y:1 z:0 duration:1]];
[node runAction:action];
// 素材放大5倍(由于我们素材的尺寸太小了)
node.transform = SCNMatrix4MakeScale(5, 5, 5);

// �创建一个摄像机并放入场景中
SCNNode *cameraNode = [SCNNode node];
cameraNode.camera = [SCNCamera camera];
[scene.rootNode addChildNode:cameraNode];

// �摆放摄像机位置
cameraNode.position = SCNVector3Make(0, 5, 15);

// 创建�灯光并放入场景中
SCNNode *lightNode = [SCNNode node];
lightNode.light = [SCNLight light];
lightNode.light.type = SCNLightTypeOmni;
lightNode.position = SCNVector3Make(0, 10, 10);
[scene.rootNode addChildNode:lightNode];

// create and add an ambient light to the scene
SCNNode *ambientLightNode = [SCNNode node];
ambientLightNode.light = [SCNLight light];
ambientLightNode.light.type = SCNLightTypeAmbient;
ambientLightNode.light.color = [UIColor darkGrayColor];
[scene.rootNode addChildNode:ambientLightNode];

// 创建一个用来展示场景的SCNView
SCNView *scnView = [[SCNView alloc] initWithFrame:self.view.bounds];

[self.view addSubview:scnView];

// 设置场景
scnView.scene = scene;

// 设置背景
scnView.backgroundColor = [UIColor blackColor];

// 允许控制摄像机位置
scnView.allowsCameraControl = YES;

// 显示数据控制台
scnView.showsStatistics = YES;

好了,编辑运行。成功运行

小怪兽

** BUT **,在实际项目中往往需要我们从服务器上将模型下载下来再来显示,然而这种做法只能是事先把素材放入项目中才能正常显示,【注意:我说的是正常显示】,这是不符合我们的需求的。如果我们把素材从服务器上下载到沙盒里,程序再直接从沙盒读取和初始化场景会出现为nil的问题。

iOS - SceneKit显示与交互3D建模(�二) 最后附上DEMO LXF3DSceneDemo

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏非著名程序员

CoordinatorLayout的使用如此简单

曾在网上找了一些关于CoordinatorLayout的教程,大部分文章都是把CoordinatorLayout、AppbarLayout、Collapsing...

19410
来自专栏Youngxj

EMLOG博客添加OwO表情教程

1846
来自专栏章鱼的慢慢技术路

Unity入门教程(下)

2223
来自专栏Python数据科学

这些世界杯球星你真的认识吗?不如通过Python来认识一下吧

回到我们的正题,对于世界杯的球星们,人们知道的一般都是C罗,梅西,德罗巴等巨星,而对一些其它球星却很少了解。对于这些球星,你认识的有多少呢?下面就跟我一起认识一...

702
来自专栏王金龙的专栏

编程语言中那些有趣的命名

      学习NodeJS的时候,一定会用到其包管理器npm。npm的字面意思是node package manager,实际的含义也是这样,但是npm真正的...

882
来自专栏wOw的Android小站

[Android]暗码机制

因为之前改过Dialer,定制过相关的暗码功能,所以没多想就直接把intent-filter加在MainActivity中了。然后测试告诉我,输入”*#*#36...

1301
来自专栏移动端开发

AVFoundation 框架初探究(一)

夜深时动笔 ----       前面一篇文章写了视频播放的几种基本的方式,算是给这个系列开了一个头,这里面最想说和探究的就是AVFoundation框架,很想...

5685
来自专栏项勇

笔记58 | Android闹钟

2013
来自专栏美丽应用

Google Now Enabler:一键开启Google Now

5594
来自专栏IT笔记

三分钟深入TT猫之故障转移

结束了一周繁忙的工作,趁着周末,小编手中的键盘早已饥渴难耐了,想知道上期省略号中发生了什么有趣的故事么?且听小编娓娓道来,结尾有彩蛋。 ? 风月前场 春风再续,...

3468

扫码关注云+社区