• 如何在SCENEKIT使用SWIFT RUNTIME动态加载COLLADA文件


    问题:今天接到一个项目,负责弄需求的美眉跟我讲能不能做一个原型能够加载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. 这个总结好像可有可无
  • 相关阅读:
    .NET微信网页开发之JS-SDK使用步骤和配置信息timestamp(时间戳),nonceStr(随机串),signature(签名),access_token(接口调用凭据)的生成获取讲解
    .NET项目中NLog的配置与使用
    ASP.NET MVC中使用jQuery Ajax通过FormData对象异步提交图片文件到服务端保存并返回保存的图片路径
    Linux CentOS上安装 MySQL 8.0.16
    微信小程序开发之多图片上传+.NET WebAPI后端服务保存图片资源
    MySQL 查询重复数据,删除重复数据保留id最小的一条作为唯一数据
    .NET轻松实现支付宝服务窗网页授权并获取用户相关信息
    .NET微信网页开发之通过UnionID机制,解决用户在不同公众号,或在公众号、移动应用之间帐号统一问题
    Navicat远程连接MySQL 提示1045
    Vs Code推荐安装插件
  • 原文地址:https://www.cnblogs.com/bigger/p/4985421.html
Copyright © 2020-2023  润新知