问题:今天接到一个项目,负责弄需求的美眉跟我讲能不能做一个原型能够加载Collada文件,流程如下:

  1. 用户用app下载Collada 压缩包(如内购项目)
  2. 压缩包解压
  3. 展示Collada文件里的内容

我开始google各种能够快速搞定需求的工具以及类库,看了下Unity3D,感觉这胖子挺臃肿的,对胖子没兴趣。苹果的SceneKit好像做3D还不错,性能高还是原生,原生态的东西味道应该不错,下面有食用方法。

步骤一:

打开不是给人看的Apple Doucmentation,经过两眼球左右互搏后有重大发现就是苹果没有教会我什么魔法能够直接搞定这个需求,我表示很沮丧。

最终决定使用简单粗暴的方法硬把.dae文件下载到沙盒然后在runtime中读取

结果Xcode爆出:

scenekit COLLADA files are not supported on this platform

我也想爆粗。。。。。

看来没办法了,只能老老实实的自己写。

步骤二:

新建项目选择Game template,SceneKit

首先,要搞个Collada文件(.dae),没弄Maya很久了,下载了个免费的blender,把弄好的的dae文件丢到art.scnassets里边去。

步骤三:

先搞两盘盘炉石或者去斗鱼看看露半球

然后呢。。。

没然后了。

步骤四:

有的时候思路会自己送上门的,想读取文件在runtime又不让我操作compile-time,那种只能看不能摸的感觉你懂的。

既然苹果能够在scnasets目录下读取.dae那肯定用了些魔法,看看build logs到底做了些什么。

显然发现了什么,嗯似乎调用了copySceneKitAsets,正是这玩意最终调用了scntool去优化.dae文件

步骤五:

要挖坑了,要搞清楚为什么请找到这个目录去挖

(/Applications/Xcode/Contents/Developer/usr/bin)

找找发现这两个宝物 copySceneKitAsets、 scntool。

步骤六:

用户付费后下一步应该调用Api加载.dae

先建一个名叫product.scnassets的文件夹

运行下边脚本

./copySceneKitAssets product-1.scnassets/ -o product-1-optimized.scnassets

压缩打包生成的文件然后丢到服务器去

步骤六:

接下来是重体力活

我是用AFNetworkingSSZipArchive

在GameViewController.m 中施工

流程大概是这样,在viewDidLoad:中加入下载zip压缩包,解压的代码

- (void)viewDidLoad {
[super viewDidLoad];
[self downloadZip];
} - (void)downloadZip { NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration]; NSURL *URL = [NSURL URLWithString:@"http://www.XXXXXXX.com/product-1-optimized.scnassets.zip"]; NSURLRequest *request = [NSURLRequest requestWithURL:URL]; NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) { NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil]; return [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]]; } completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) { NSLog(@"File downloaded to: %@", filePath); // Unzip the archive NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; NSString *inputPath = [documentsDirectory stringByAppendingPathComponent:@"/product-1-optimized.scnassets.zip"]; NSError *zipError = nil; [SSZipArchive unzipFileAtPath:inputPath toDestination:documentsDirectory overwrite:YES password:nil error:&zipError]; if( zipError ){ NSLog(@"[GameVC] Something went wrong while unzipping: %@", zipError.debugDescription); }else { NSLog(@"[GameVC] Archive unzipped successfully"); [self startScene];
} }]; [downloadTask resume];
}

东西下载完了然后就是加载了

// Load the downloaded scene

NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];

   documentsDirectoryURL = [documentsDirectoryURL URLByAppendingPathComponent:@"product-1-optimized.scnassets/cube.dae"];

SCNSceneSource *sceneSource = [SCNSceneSource sceneSourceWithURL:documentsDirectoryURL options:nil];

// Get reference to the cube node

SCNNode *theCube = [sceneSource entryWithIdentifier:@"Cube" withClass:[SCNNode class]];

简单说一下就是是用SCNSceneSource、SCNNode加载,好像等于没说看代码就好。

接下来就是流氓导演最熟悉的步骤,布景、灯光、摄像机。

// Create a new scene

SCNScene *scene = [SCNScene scene];  

// create and add a camera to the scene

SCNNode *cameraNode = [SCNNode node];

cameraNode.camera = [SCNCamera camera];

[scene.rootNode addChildNode:cameraNode];

// place the camera

cameraNode.position = SCNVector3Make(0, 0, 15);

// create and add a light to the scene

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];

这是我最喜欢的部分模特上场

// retrieve the SCNView

SCNView *scnView = (SCNView *)self.view;

// set the scene to the view

scnView.scene = scene;

// allows the user to manipulate the camera

scnView.allowsCameraControl = YES;

// show statistics such as fps and timing information

scnView.showsStatistics = YES;

// configure the view

scnView.backgroundColor = [UIColor blackColor];

习惯性总结:

  1. 从服务器拿到Collada zip的压缩包
  2. 解压
  3. 读到内存里
  4. 展示
  5. 这个总结好像可有可无

如何在SCENEKIT使用SWIFT RUNTIME动态加载COLLADA文件的更多相关文章

  1. Java_Java中动态加载jar文件和class文件

    转自:http://blog.csdn.net/mousebaby808/article/details/31788325 概述 诸如tomcat这样的服务器,在启动的时候会加载应用程序中lib目录下 ...

  2. Android应用安全之外部动态加载DEX文件风险

    1. 外部动态加载DEX文件风险描述 Android 系统提供了一种类加载器DexClassLoader,其可以在运行时动态加载并解释执行包含在JAR或APK文件内的DEX文件.外部动态加载DEX文件 ...

  3. js动态加载css文件和js文件的方法

    今天研究了下js动态加载js文件和css文件的方法. 网上发现一个动态加载的方法.摘抄下来,方便自己以后使用 [code lang="html"] <html xmlns=& ...

  4. 两种动态加载JavaScript文件的方法

    两种动态加载JavaScript文件的方法 第一种便是利用ajax方式,第二种是,动静创建一个script标签,配置其src属性,经过把script标签拔出到页面head来加载js,感乐趣的网友可以看 ...

  5. QUiLoader 动态加载.ui文件

    动态加载UI文件是指,用 Qt Designer 通过拖拽的方式生产.ui 文件.不用 uic工具把.ui 文件变成等价的 c++代码,而是在程序运行过程中需要用到UI文件时,用 QUiLoader ...

  6. 动态加载JS文件,并根据JS文件的加载状态来执行自己的回调函数

    动态加载JS文件,并根据JS文件的加载状态来执行自己的回调函数, 在很多场景下,我们需要在动态加载JS文件的时候,根据加载的状态来进行后续的操作,需要在JS加载成功后,执行另一方法,这个方法是依托在加 ...

  7. 详解QUiLoader 动态加载.ui文件

    http://blog.chinaunix.net/uid-13838881-id-3652523.html 1.适用情况: 动态加载UI文件是指,用 Qt Designer 通过拖拽的方式生产.ui ...

  8. ExtJS4.x动态加载js文件

    动态加载js文件是ext4.x的一个新特性,可以有效的减少浏览器的压力,提高渲染速度.如动态加载自定义组件 1.在js/extjs/ux目录下,建立自定义组件的js文件. 2.编写MyWindow.j ...

  9. Ext JS学习第十天 Ext基础之动态加载JS文件(补充)

    此文用来记录学习笔记: •Ext4.x版本提供的一大亮点就是Ext.Loader这个类的动态加载机制!只要遵循路径规范,即可动态加载js文件,方便把自己扩展组件动态加载进来,并且减轻浏览器的压力. • ...

随机推荐

  1. add number

    // io.cpp #include <iostream> int readNumber() { std::cout << "Enter a number: &quo ...

  2. 循序渐进Python3(十二) --2--  web框架之django简单实现oracle数据库操作

    在 Django 中构建 Oracle 数据库支持的 Web 应用程序 了解如何配置 Django 以便与 Oracle 数据库交互,并使用 ORM 进行数据库连接.             产能在软 ...

  3. C#批量插入数据到Sqlserver中的三种方式

    本篇,我将来讲解一下在Sqlserver中批量插入数据. 先创建一个用来测试的数据库和表,为了让插入数据更快,表中主键采用的是GUID,表中没有创建任何索引.GUID必然是比自增长要快的,因为你生 成 ...

  4. Python学习资料下载地址(转)

    [转]Python学习资料和教程pdf 开发工具: Python语言集成开发环境 Wingware WingIDE Professional v3.2.12 Python语言集成开发环境 Wingwa ...

  5. iOS(视图控制器转场)

    转场需要提供转场代理,不使用默认的代理则需要自己实现代理方式,有UINavigationController.UITabBarController.UIViewController三种代理,实现以下三 ...

  6. MyBatis复习【简单配置CRUD】

    这里的案例集成了log4j的日志框架,项目架构: 用到的jar文件 添加配置文件:mybatis-config.xml  和dao层配置文件StudentDao.xml 这里书写了个简单的案例仅为了说 ...

  7. C# 委托和事件 与 观察者模式(发布-订阅模式)讲解 by天命

    使用面向对象的思想 用c#控制台代码模拟猫抓老鼠 我们先来分析一下猫抓老鼠的过程 1.猫叫了 2.所有老鼠听到叫声,知道是哪只猫来了 3.老鼠们逃跑,边逃边喊:"xx猫来了,快跑啊!我是老鼠 ...

  8. 使用HttpClient 发送get、post请求,及其解析xml返回数据

    一.关于HttpClient的使用: 可以参考这个博客地址,这里有详细的介绍,需要的可以先看一下: 地址是:http://blog.csdn.net/wangpeng047/article/detai ...

  9. oracle分页查询sql

    select * from( select shopid,rownum rn from p_shopinfo where is_hot=1 and rownum <=6 order by sho ...

  10. iOS系统导航/自绘制导航路线

    系统自带导航 /** 系统自带导航 当前位置导航到目的地 1.根据目的地进行地理编码 2.把当前位置和目的地封装成MKMapItem对象 3.使用 MKMapItem openMapsWithItem ...