2016-02-19 242 views
4

我對此很陌生。我的第一個問題就出現了。Objective-C Scenekit:從外部導入OBJ文件併爲其着色

我用SceneKit構建了一個對象加載器。我得到了路徑,對象是可用的,但我不知道如何才能着色顯示的對象。

ScnScene *testScene = [SCNScene sceneWithURL:url options:nil error:NULL]; 
testScene.background.contents = [UIImage imageWithName:@"color.png"]; 

[self.mainView.scene.rootnode addChildNode:testScene.rootNode]; 

這沒有奏效。我也試過用:

SCNMaterialProperty *testColor = [SCNMaterialProperty materialPropertyWithContents [UIImage imageNamed:@"color.png"]]; 
testScene.rootnode.geometry.materials = testcolor; 

或者:

SCNMaterial *testColor = [SCNMaterial material]; 
testColor.diffuse.contesnts = [UIColor redColor]; 
testScene.rootnode.geometry.firstMaterial = testColor; 

沒有什麼工作。當我啓動應用程序時,每個對象都會顯示。到目前爲止,OBJ-Loader工作得很好。但一切仍然灰暗。我完全不知道如何爲顯示的對象着色。有沒有人爲我提示/想法/解決方案?

Btw。我想避免我必須手動構建OBJ信息中的幾何圖形。所以我試圖通過SCNScene解決這個問題。

回答

6

主要問題是SCNScene導入不起作用。因此,正確的解決方案是將obj.file導入SCNNode,將所選顏色(或圖像)的SCNMaterial添加到SCNNode,並將SCNNode添加到SCNScene。要加載obj.file,您需要通過Model IO Framework導入該文件。

我會給我一些代碼,我如何使它豐富多彩。

#import <SceneKit/SceneKit.h> 
#import <ModelIO/ModelIO.h> 
#import <SceneKit/ModelIO.h> 

...

@property (nonatomic) SCNView* mainView; 

....

MDLAsset *asset = [[MDLAsset alloc] initWithURL:url];  
SCNScene *scene = [SCNScene scene]; 
SCNNode *node = [SCNNode nodeWithMDLObject:[asset objectAtIndex:0]]; 

SCNMaterial *material = [SCNMaterial material]; 
material.diffuse.contents = [UIColor colorWithHue:0 saturation:0.1 brightness:0.5 alpha:1]; 
node.geometry.firstMaterial = material; 

[scene.rootNode addChildNode:node]; 
[self.mainView.scene.rootNode addChildNode:scene.rootNode]; 

或者你可以通過這個添加顏色:

material.diffuse.contents = [UIImage imageNamed:@"farbe.png"];

現在你可以導入一個ny obj.file外部(來自您喜歡的任何選定文件夾)併爲其着色。

感謝SGlindemann,cashmash和Hal Mueller,他幫助我們找到了解決方案。


更新(2017年1月29日)

不知怎的,上述方式不工作了。我沒有弄清楚什麼改變了。但我做了另一個代碼,使加載的3D文件成爲可能(從mainBundle,而不是外部)。在這裏,我從ViewController.m調用的SCNNode類開始。 SCNScene設置在ViewController中。以下是我爲SCNNode課寫的代碼。

在開始之前,將.obj和.mtl文件(兩者同名)放入Xcode項目中。您不需要將其轉換爲場景。

#import <ModelIO/ModelIO.h> 
#import <SceneKit/ModelIO.h> 

...

@property (nonatomic) SCNNode *objectNode; 

...

NSString* path = [[NSBundle mainBundle] 
      pathForResource:[NSString stringWithFormat:@"name of the obj.file"] 
      ofType:@"obj"]; 
NSURL *url = [NSURL fileURLWithPath:path]; 
MDLAsset *asset = [[MDLAsset alloc]initWithURL:url]; 

// Create the Block 
self.objectNode = [SCNNode nodeWithMDLObject:[asset objectAtIndex:0]]; 


[self addChildNode: self.objectNode]; 

return self; 

這回self已被添加到您的視圖。

[self.view.scene.rootNode addChildNode:returnedObj]; 

MDLAsset加載的obj文件與相應的.mtl文件和PNG-文件。我使用這段代碼從MagicaVoxel加載對象(此時導出obj + mtl + png)。我還沒有深入。

我沒有試過這個代碼與外部加載或通過SCNMaterial手動輸入顏色。所以沒有說明這是否有效。我沒有嘗試。

+0

嘿,我試過這段代碼,但我只能看到白色屏幕。沒有3d模型。你能幫我嗎? –

+0

嘿,我也遇到了這個問題。不知何故,他們改變了一些東西,使外部負載不再工作。我做了另一個正在工作的代碼(通過mainbundle +使用.obj和.mtl文件加載)。 我用我的新代碼更新了上面的帖子。我希望它有幫助。 –

2

你的第一個例子將設置場景的背景,但對你的對象什麼都不做。

你的第二個例子應該給你一些編譯器警告。您正在分配一個SCNMaterialPropertytestScene.rootnode.geometry.materials,這需要一個SCNMaterial(而不是SCNMaterialProperty)的數組。這是你的真實代碼嗎?

最後一個例子根本不應該編譯:你拼錯contentscontesnts。除此之外,它應該工作。

請注意,MDLAsset可以導入OBJ文件並返回SCNNode。見How do you convert Wavefront OBJ file to an SCNNode with Model I/O。如果對象是您的項目隨附的資產,請將其保存爲SCNScene(這是緊湊且經過優化的),然後發送,而不是原始的OBJ。

+0

非常感謝您的回覆。我手動重寫了代碼,因爲那時我的帶有代碼的筆記本電腦被另一個人使用。出現了錯誤的拼寫代碼。對不起。 我按照你的建議使用了'MDLAsset'。總的來說,它無法通過'SCNMaterial'添加一個顏色到'SCNScene',但是如果我將obj.file導入到'SCNNode',它就可以工作。所以我第一次嘗試的一切都是錯誤的。 我將添加我發現的解決方案,讓所有事情變得更加豐富多彩。 但非常感謝你。沒有你的'MDLAsset'插入這個問題會讓我發瘋。 –