Objective-C Scenekit:从外部导入 OBJ 文件并为其着色
Objective-C Scenekit: Import OBJ-File externally and color it
我是新手。我的第一个问题来了。
我用 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 运行良好。但一切仍然是灰色的。我完全不知道如何为显示的对象着色。有人 hint/idea/solution 给我吗?
顺便说一句。我想避免必须手动从 OBJ 信息构建几何体。所以我尝试通过SCNScene解决这个问题。
您的第一个示例将设置场景的背景,但不对您的对象执行任何操作。
你的第二个例子应该给你一些编译器警告。您正在将单个 SCNMaterialProperty
分配给 testScene.rootnode.geometry.materials
,它需要一个 SCNMaterial
的数组(而不是 SCNMaterialProperty
)。那是你的真实代码吗?
最后一个示例根本不应该编译:您将 contents
拼错为 contesnts
。除此之外,它应该可以工作。
请注意,MDLAsset
可以导入 OBJ 文件,return 可以导入 SCNNode
。参见 。如果该对象是您将随项目一起运送的资产,请将其另存为 SCNScene
(紧凑且经过优化),然后运送,而不是原始 OBJ。
主要问题是 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"];
现在您可以从外部(从您喜欢的任何选定文件夹)导入任何 obj.file 并为其着色。
感谢 SGlindemann、cashmash 和 Hal Mueller,他们帮助找到了该解决方案。
更新 (29.1.2017)
不知何故,上面的方法不再起作用了。我还没有弄清楚发生了什么变化。但是我编写了另一个代码,使 3D 文件的加载成为可能(来自 mainBundle
,而不是外部)。这里我从 SCNNode
class 开始,它被 ViewController.m
调用。 SCNScene
设置在 ViewController
中。下面是我为 SCNNode
class.
编写的代码
开始之前,将 .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
手动输入颜色的代码。所以没有声明这是否有效。我没试过。
我是新手。我的第一个问题来了。
我用 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 运行良好。但一切仍然是灰色的。我完全不知道如何为显示的对象着色。有人 hint/idea/solution 给我吗?
顺便说一句。我想避免必须手动从 OBJ 信息构建几何体。所以我尝试通过SCNScene解决这个问题。
您的第一个示例将设置场景的背景,但不对您的对象执行任何操作。
你的第二个例子应该给你一些编译器警告。您正在将单个 SCNMaterialProperty
分配给 testScene.rootnode.geometry.materials
,它需要一个 SCNMaterial
的数组(而不是 SCNMaterialProperty
)。那是你的真实代码吗?
最后一个示例根本不应该编译:您将 contents
拼错为 contesnts
。除此之外,它应该可以工作。
请注意,MDLAsset
可以导入 OBJ 文件,return 可以导入 SCNNode
。参见 SCNScene
(紧凑且经过优化),然后运送,而不是原始 OBJ。
主要问题是 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"];
现在您可以从外部(从您喜欢的任何选定文件夹)导入任何 obj.file 并为其着色。
感谢 SGlindemann、cashmash 和 Hal Mueller,他们帮助找到了该解决方案。
更新 (29.1.2017)
不知何故,上面的方法不再起作用了。我还没有弄清楚发生了什么变化。但是我编写了另一个代码,使 3D 文件的加载成为可能(来自 mainBundle
,而不是外部)。这里我从 SCNNode
class 开始,它被 ViewController.m
调用。 SCNScene
设置在 ViewController
中。下面是我为 SCNNode
class.
开始之前,将 .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
手动输入颜色的代码。所以没有声明这是否有效。我没试过。