美文网首页iOS企业级开发实用技术iOS Developer程序员
iOS - SceneKit显示与交互3D建模(一)

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

作者: LinXunFeng | 来源:发表于2017-05-18 23:39 被阅读4193次

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

    相关文章

      网友评论

      • CC_iOS:想问下坐着,如何入控制他的旋转,比如我点击一个然后给它一个 X Y Z值他就会旋转到我指定的角度,只旋转一次,而不是一直旋转。
        Kylin17:点击事件里执行 [SCNNode1 runAction:[SCNAction rotateByX:0 y:2 z:0 duration:1]];

      本文标题:iOS - SceneKit显示与交互3D建模(一)

      本文链接:https://www.haomeiwen.com/subject/zjmjxxtx.html