首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用ModelIO的混合拓扑(四/三)

使用ModelIO的混合拓扑(四/三)
EN

Stack Overflow用户
提问于 2018-01-10 10:46:38
回答 1查看 326关注 0票数 3

我正在使用ModelIO导入一些简单的OBJ资产,如下所示:

代码语言:javascript
复制
let mdlAsset = MDLAsset(url: url, vertexDescriptor: nil, bufferAllocator: nil, preserveTopology: true, error: nil)

..。然后将它们添加到SceneKit SCN文件中。但是,每当我有两个四边形/三角形的网格(通常是这种情况,例如眼球网格),结果网格是混乱的:

Incorrect mesh topology

重新拓扑化不是一个好的选择,因为我有时会有非常特定拓扑的低多边形网格,所以我不能只是将preserveTopology设置为false……我需要一个具有可变拓扑结构(即MDLGeometryType.variableTopology)的结果。

如何正确导入这些文件并保留其原始拓扑?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-01-10 21:14:14

11月25日,我在Apple bug Reporter上报告了这是一个错误,错误id: 35687088

摘要:实际上并不保留原始拓扑。相反,它将几何体转换为所有四边形,严重扰乱了3D模型。根据其名称,它的行为应该与模型IO资产加载的preserveTopology完全相同。

再现步骤:使用加载同时具有三角形和多边形的OBJ文件,并使用ModelIO的preserveTopology将相同的文件加载到MDLMesh中。请注意,它只适用于后者。即使在基于MDLMesh创建新的SCNGeometry时,它也会再次使网格“四边形”,使其仅包含四边形(虽然它应该支持3边形或更高)。

12月13日,我收到了一个回复,要求提供示例代码和资产,这是我在两天后提供的。从那以后,我还没有收到回复(希望是因为他们只是忙于从假日季节赶过来…)。

正如我在bug报告的摘要中提到的,使用模型I/O加载资源确实可以正常工作,但是当您基于该MDLMesh创建SCNNode时,它会再次弄乱几何体。

在我的例子中,我加载的OBJ文件有一种已知的格式,因为它们总是与我的应用程序一起导出的文件(没有法线,颜色,UV)。因此,我所做的是手动将MDLMesh的信息(缓冲区、面拓扑等)加载到数组中,然后从数组中手动创建一个SCNGeometry。我没有为你提供一个完整的单独的代码片段,因为它很多,并且混合了很多特定于我的应用程序的代码,它在Objective C中。

代码语言:javascript
复制
    NSError *scnsrcError;
    MDLAsset *asset = [[MDLAsset alloc] initWithURL:objURL vertexDescriptor:nil bufferAllocator:nil preserveTopology:YES error:&scnsrcError];
    NSLog(@"%@", scnsrcError.localizedDescription);

    MDLMesh * newMesh = (MDLMesh *)[asset objectAtIndex:0];

    for (MDLSubmesh *faces in newMesh.submeshes) {

        //MDLSubmesh *faces = newMesh.submeshes.firstObject;
        MDLMeshBufferData *topo = faces.topology.faceTopology;
        MDLMeshBufferData *vertIx = faces.indexBuffer;
        MDLMeshBufferData *verts = newMesh.vertexBuffers.firstObject;

        int faceCount = (int)faces.topology.faceCount;

        int8_t *faceIndexValues = malloc(faceCount * sizeof(int8_t));
        memcpy(faceIndexValues, topo.data.bytes, faceCount * sizeof(int8_t));

        int32_t *vertIndexValues = malloc(faces.indexCount * sizeof(int32_t));
        memcpy(vertIndexValues, vertIx.data.bytes, faces.indexCount * sizeof(int32_t));

        SCNVector3 *vertValues = malloc(newMesh.vertexCount * sizeof(SCNVector3));
        memcpy(vertValues, verts.data.bytes, newMesh.vertexCount * sizeof(SCNVector3));

    ....
    ....
    }

简而言之,SceneKit中的preserveTopology选项不能正常工作。为了从模型I/O中的工作版本转换到SceneKit,我基本上必须编写我自己的转换器。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48179571

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档