gpt4 book ai didi

ios - 具有 ModelIO 的混合拓扑(四/三)

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:30:27 25 4
gpt4 key购买 nike

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

let mdlAsset = MDLAsset(url: url, vertexDescriptor: nil, bufferAllocator: nil, preserveTopology: true, error: nil)

... 然后将它们添加到 SceneKit SCN 文件中。但是,每当我有同时具有四边形/三边形的网格时(通常是这种情况,例如眼球网格),生成的网格就会困惑:

Incorrect mesh topology

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

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

最佳答案

我于 11 月 25 日在 Apple Bug Reporter 上报告了这个错误,错误 ID:35687088

总结:SCNSceneSourceLoadingOptionPreserveOriginalTopology 实际上并不保留原始拓扑。相反,它将几何体转换为所有四边形,严重破坏了 3D 模型。根据它的名字,它的行为应该与模型 IO Assets 加载的 preserveTopology 完全一样。

重现步骤:使用 SCNSceneSourceLoadingOptionPreserveOriginalTopology 加载一个包含三角形和多边形的 OBJ 文件,并使用 ModelIO 的 preserveTopology 将同一文件加载到 MDLMesh 中。请注意它如何仅适用于后者。即使您基于 MDLMesh 创建新的 SCNGeometry,它也会再次“四化”网格以仅包含四边形(同时它应该支持 3 边形及以上)。

12 月 13 日,我收到了回复,要求我在 2 天后提供示例代码和 Assets 。从那以后我没有收到回复(希望是因为他们只是忙于 catch 假期......)。

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

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

    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 选项无法正常工作。要从 Model I/O 中的工作版本转换为 SceneKit,我基本上必须编写自己的转换器。

关于ios - 具有 ModelIO 的混合拓扑(四/三),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48179571/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com