• 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文件并显示了。
  • 相关阅读:
    【java/jdbc】求Oracle表中字符串类型、Data类型、TimeStamp类型字段的时间差(时分秒hms形式)
    转贴【Oracle.DBA】Oracle temp表空间爆满的处理方法
    【Oracle/sqlplus】利用Spool批量删除系统中的表
    在Win/Linux如何连续跟踪应用的CPU和内存使用率
    【Java.异常】记一次一千三百万记录的表迁移时发生的异常Java.sql.SQLException,关闭的ResultSet;findColumn
    jdbc连postgresql库时schema设置
    2ESP8266转CAN总线和RS232通讯模块CAN总线通信测试Arduino
    21物联网开发终端管理篇安装PHP,测试GET,POST接口(.Windows系统)
    11物联网开发终端管理篇java从MQTT获取设备数据,并通过Druid连接池把数据写入MySQL数据库(Linux系统,宝塔)
    001STM32+MN316(NBIOT)基本控制篇(阿里云物联网平台)C#,网页,android,微信小程序,单片机等使用MQTT接入阿里云物联网平台
  • 原文地址:https://www.cnblogs.com/baitongtong/p/5884647.html
Copyright © 2020-2023  润新知