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 条评论
登录 后参与评论

相关文章

来自专栏崔庆才的专栏

腾讯云主机上测试BootStrap4编译FlexBox

最近在开发一个移动端适配的网站,使用了materi-ui框架,基于React。使用materi-ui时,已经内置了许多样式,但是bootstrap的一些多余样式...

2040
来自专栏黒之染开发日记

在手机web中播放视频(使用js,不使用video标签,支持直播)

jsmpeg只支持mpeg格式的视频,jsmpeg官方建议用ffmpeg来转格式。ffmpeg下载地址

2435
来自专栏ASP.NET MVC5 后台权限管理系统

.Net 转战 Android 4.4 日常笔记(9)--常用组件的使用方法[附源码]

经过两天的学习,把常用的组件都学习了一遍,并做成了App 学习可能真没有捷径,跟学习html有点类似,都是一个控件一个控件学习并使用,最后拼凑成一个系统 链接:...

1756
来自专栏生信技能树

【直播】我的基因组46:SNV突变(96种)频谱的制作

昨天我们学习了正常情况下,6种SNV(C>A, C>G, C>T, T>A, T>C, T>G)突变频谱的制作,但是如果考虑到突变的上下文,就可以变成96种(如...

3237
来自专栏生信技能树

SNV突变(96种)频谱的制作

昨天我们学习了正常情况下,6种SNV(C>A, C>G, C>T, T>A, T>C, T>G)突变频谱的制作,但是如果考虑到突变的上下文,就可以变成96种(如...

2785
来自专栏姬小光

姬小光前端兴趣班【第008期】- 真正的切图大法

上一期我们使用了 word 转存大法来生成网页,主要是为了帮助大家理解表格布局的原理。那么今天我们就来学习一下真正的切图大法。

762
来自专栏编程

2018 年初值得关注的 25 个新 Android 库和项目

协作翻译 原文:25 new Android libraries and projects to check at the beginning of 2018 ...

21710
来自专栏吉浦迅科技

如何在Jetson TX2上使用CSI相机(续)

8803
来自专栏iOS Developer

Apple Pay强势来袭,开发者应做的事情--转自Bison的技术博客

993
来自专栏ASP.NET MVC5 后台权限管理系统

ASP.NET MVC5+EF6+EasyUI 后台管理系统(45)-工作流设计-设计步骤

步骤设计很重要,特别是规则的选择。 我这里分为几个规则 1.按自行选择(在起草时候自行选审批人,比较灵活) 2.按上级(无需指定,当时需要知道用户的上司是谁,可...

2097

扫码关注云+社区