上篇文章iOS – SceneKit顯示與互動3D建模(一)中我們介紹了sceneKit的簡單使用,還提到一個需求,就是要從沙盒中動態載入場景
猜想階段
將素材拖至沙盒的Documents資料夾下,模擬素材已從伺服器下載至本地

接下來拼接素材地址,執行後一片漆黑,由於沒什麼好看的就不放圖了。從截圖中可以看到了,scene為空,自然也就看不到任何東西。

那如果我們把素材Menchi.dae學demo一樣放至scnassets資料夾中呢?

經過實踐,結果還是一樣,也是nil。

有人就說了demo中明明是scn檔案,不是dae。這裡我要提一下,SceneKit是可以從scn檔案或者dae檔案初始化場景的,而如果換成從scn檔案初始化場景,scene的確不為nil,但是一樣是一片漆黑,不相信的朋友可以自己試下。
scn是xcode能夠識別的場景檔案,該檔案本身就是scene,所以不為nil,而如果是dae初始化場景,dae檔案只是作為一個節點加入到新建的scene中,由於沒有新建scene自然也就新增不了這個素材節點。
探索階段
百思不得其解,只好來看看build過程有什麼特殊動作了,果不其然有貓膩

取其精華,格式如下
// artLXF只是事例做法,可以改為你想要顯示的名字
copySceneKitAssets art.scnassets -o artLXF.scnassets
複製程式碼
現在就大致明瞭了,SceneKit使用了copySceneKitAssets指令碼對art.scnassets進行了不為人知的處理,這個過程還需要用到另一個指令碼工具scntool,這兩個檔案存放的目錄如下:
/Applications/Xcode.app/Contents/Developer/usr/bin/
複製程式碼
至於說它是不為人知的處理過程,是因為我沒有看到蘋果官方文件中有說明,也可能是我沒找著~~
大膽實踐
在桌面上新建並進入一個叫LXFScene的資料夾,再新建一個art資料夾並新增字尾【.scnassets】,存入素材Menchi.dae,將需要的兩個檔案(copySceneKitAssets和scntool)提取出來也放入LXFScene目錄下

開啟終端,先cd到LXFScene目錄,如圖打入命令
./copySceneKitAssets art.scnassets -o artLXF.scnassets
複製程式碼


將新的scnassets拖入沙盒的Document資料夾下,更名為art.scnassets,再次執行程式看看

測試成功!就是我們的素材小了點,改下尺寸就好了
SCNNode *mechiNode = scene.rootNode.childNodes.firstObject;
mechiNode.transform = SCNMatrix4MakeScale(5, 5, 5);
複製程式碼
這樣我們就可以讓後臺先將處理好的scnassets資料夾打包放到伺服器上,我們下載下來後解壓使用就好了~
給模型新增點選事件
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapTest:)];
[scnView addGestureRecognizer:tap];
複製程式碼
- (void)tapTest:(UITapGestureRecognizer *)tap {
// 獲取模型點選處的三維座標
SCNVector3 projectedOrigin = [self.scnView projectPoint:SCNVector3Zero];
CGPoint vp = [tap locationInView:self.scnView];
SCNVector3 vpWithZ = SCNVector3Make(vp.x, vp.y, projectedOrigin.z);
SCNVector3 worldPoint = [self.scnView unprojectPoint:vpWithZ];
NSLog(@"x: --- %f y: --- %f z: --- %f", worldPoint.x, worldPoint.y, worldPoint.z);
}
複製程式碼
最後附上DEMO LXF3DSceneDemo