zoukankan      html  css  js  c++  java
  • iOS



    SceneKit是ios8之后苹果推出了一个3D模型渲染框架。

    SceneKit现在可以支持有限的几种模型,截止到我写这篇文章为止似乎只有.dae和.abc后一种模型我没有使用过。这篇文章只针对.dae模型写。
      首先如果是希望加载一个已有的,不需要程序在运行的时候动态添加的dae模型。那么我们可以直接新建一个game类型的工程。在选项中选择SceneKit,在程序中加载自带模型的那句话中将模型名称替换即可。本文主要讲一下如何导出dae模型,并在server端动态下载并显示。
      首先我们手中有一个.stl或者其他的模型文件,将模型文件转换成.dae文件我使用Blender。
    blender for mac版下载 我放在我的GitHub上需要自行下载:https://github.com/baitongtong/Blender.git
      (1)在Blender中新建场景
      (2)在右上侧栏中将自动生成的Cube、Camera等3个物体删掉
      (3)导入我们已有的模型文件
      (4)调整我们的模型文件的方向、大小
      (5)在右上侧栏更改模型文件及子文件的名字为你要导出的dae文件的名字(这一步很重要!)
      (6)在左侧栏中Edit Options中点击Smooth
      (7)File->export->dae
      (8)在接下来的页面中,我们选择导出的位置和文件的名字,并且在左侧选项Texture中选择include material texture(同样重要!)
      接下来我们在桌面上新建一个文件夹,暂时起名为model,更改后缀为.scnassets,将我们生成好的模型文件拷贝进去。SceneKit对于动态添加文件夹写了两个脚本。不太清楚作用原理是什么,以后再研究吧。暂时知道怎么用就行。将copySceneKitAssets、scntool文件拷贝到model.scnassets所在的目录下,进入终端并cd到该目录下,运行
    1 ./copySceneKitAssets model.scnassets -o model-o.scnassets

    如果终端没有报错,并且生成了model-o.scnassets,则代表运行成功。
      接下来我们把生成的model-o.scnassets文件打包zip文件,目的是为了能让iPhone客户端下载的时候文件更小。
      打包好了之后上传至服务器即可。
      两个可执行文件下载链接 http://download.csdn.net/detail/u013588047/8937773  

      接下来是重头戏,如何在程序中下载,解压,并显示呢。
      下载解压我使用了两个开源框架 AFNetworking 和 SSZipArchive ,朋友们可以自行查阅使用方法。
      一步一步来,先是下载,解压

    - (void)downloadZip {
        
        NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
        AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
        //这里我们用本地链接替代一下,可以使用任意url链接
        NSURL *URL = [NSURL URLWithString:@"file:///User/name/Desktop/model.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);
            
            //对文件解压
            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];
    }

    而对于3d模型场景的创建,我们使用SCNSceneSource,代码如下
    1 NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
    2//这里的dae文件名字是我们导出时定义的文件名,下面一段代码中加载的SCNNode是我们之前在面板中改过的模型名
    3 documentsDirectoryURL = [documentsDirectoryURL URLByAppendingPathComponent:@"model.scnassets/cube.dae"];
    4
    5 SCNSceneSource *sceneSource = [SCNSceneSource sceneSourceWithURL:documentsDirectoryURL options:nil];
    然后我们加载.dae文件中的模型,作为一个SCNNode,名字为我们在一开始改过的模型名
    1 SCNNode *theCube = [sceneSource entryWithIdentifier:@"Cube" withClass:[SCNNode class]];

    最后我们设置一下灯光等效果,其实是新建game文件中设置好了的,我们要做的是将SCNNode *theCube加载到Scene中
    // 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];
    
    // Add our cube to the scene
    [scene.rootNode addChildNode:theCube];
    
    // 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];

    这样我们就可以动态下载一个dae文件并显示了。
  • 相关阅读:
    68
    56
    Django manager 命令笔记
    Django 执行 manage 命令方式
    Django 连接 Mysql (8.0.16) 失败
    Python django 安装 mysqlclient 失败
    H.264 SODB RBSP EBSP的区别
    FFmpeg—— Bitstream Filters 作用
    MySQL 远程连接问题 (Windows Server)
    MySQL 笔记
  • 原文地址:https://www.cnblogs.com/baitongtong/p/5884647.html
Copyright © 2011-2022 走看看