前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >iOS - SceneKit显示与交互3D建模(一)

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

作者头像
LinXunFeng
发布2018-06-29 15:23:07
4.1K0
发布2018-06-29 15:23:07
举报
文章被收录于专栏:LinXunFeng的专栏LinXunFeng的专栏

最近公司要求在手机上显示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

代码语言:javascript
复制
#import <SceneKit/SceneKit.h>

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

代码语言:javascript
复制
// �初始化一个场景
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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017.05.18 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 初出茅庐
  • 初窥门径
  • 牛刀小试
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档