將.stl文件轉化為.dae並動態加載到SceneKit顯示(ios中顯示3d模型)


      ios8之后蘋果推出了一個3D模型渲染框架。SceneKit。但是國內針對這方面的教程並不是很多。前兩天搞了一下也是一頭霧水,終於把最基礎的內容搞明白了之后,寫下這篇隨筆作為cnblogs的開篇,希望能一直寫下去。

  SceneKit現在可以支持有限的幾種模型,截止到我寫這篇文章為止似乎只有.dae和.abc后一種模型我沒有使用過。這篇文章只針對.dae模型寫。

  首先如果是希望加載一個已有的,不需要程序在運行的時候動態添加的dae模型。那么我們可以直接新建一個game類型的工程。在選項中選擇SceneKit,在程序中加載自帶模型的那句話中將模型名稱替換即可。本文主要講一下如何導出dae模型,並在server端動態下載並顯示。

  首先我們手中有一個.stl或者其他的模型文件,將模型文件轉換成.dae文件我使用Blender。

  (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 ,朋友們可以自行查閱使用方法。

  一步一步來,先是下載,解壓

 1 - (void)downloadZip {
 2     
 3     NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
 4     AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
 5     //這里我們用本地鏈接替代一下,可以使用任意url鏈接
 6     NSURL *URL = [NSURL URLWithString:@"file:///User/name/Desktop/model.scnassets.zip"];
 7     NSURLRequest *request = [NSURLRequest requestWithURL:URL];
 8     
 9     NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
10         NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
11         return [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]];
12     } completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
13         NSLog(@"File downloaded to: %@", filePath);
14         
15         //對文件解壓
16         NSArray  *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
17         NSString *documentsDirectory = [paths objectAtIndex:0];
18         NSString *inputPath = [documentsDirectory stringByAppendingPathComponent:@"/product-1-optimized.scnassets.zip"];
19         
20         NSError *zipError = nil;
21         
22         [SSZipArchive unzipFileAtPath:inputPath toDestination:documentsDirectory overwrite:YES password:nil error:&zipError];
23         
24         if( zipError ){
25             NSLog(@"[GameVC] Something went wrong while unzipping: %@", zipError.debugDescription);
26         }else {
27             NSLog(@"[GameVC] Archive unzipped successfully");
28             [self startScene];
29         }
30         
31     }];
32     [downloadTask resume];
33 }

而對於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文件並顯示了。

 

注:原創文章,轉載請注明原作者。

后記:剛剛開始進行ios開發,文章中肯定有很多不正確與缺漏的地方,也有很多不求甚解的地方,希望大家多多指教。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM