菜鸟教程小白 发表于 2022-12-12 19:21:06

iOS 将 .obj 文件导入模型 I/O 而不复制顶点


                                            <p><p>我正在尝试使用模型 I/O 框架导入 .obj 文件以在 Scene Kit 中使用。我最初使用简单的 MDLAsset initWithURL: 函数,但是在将网格转移到 SCNGeometry 之后,我意识到这个函数正在对网格进行三角剖分,这样每个面都有 3 个唯一的顶点,并且在边界面的同一位置有单独的顶点。这导致我的其他函数出现一些重大问题,因此我尝试通过使用 MDLAsset initWithURL:vertexDescriptor:bufferAllocator:preserveTopology 函数来修复它,preserveTopology 设置为 YES,描述符/分配器设置为默认值,nil。这种保留拓扑解决了我复制顶点的问题,所以面/边都很好,但在这个过程中我丢失了法线数据。</p>

<p>失去法线,我不是指多重索引,我的意思是在将 preserveTopology 设置为 YES 后,缓冲区根本不包含任何法线值。而之前它是 v1/n1/v2/n2... 并且步幅是 24 个字节(3 个维度 *4 个字节/ float* 2 个属性),现在缓冲区的前半部分是 v1/v2/...步幅为 12,缓冲区的整个第二半只有 0.0 个 float 。 </p>

<p>这也有点奇怪,当您查看几何的 SCNGeometrySources 时,有 2 个源,1 个具有语义 kGeometrySourceSemanticVertex,1 个具有语义 kGeometrySourceSemanticNormal。您会认为语义顶点源将包含位置数据,而语义法线源将包含法线数据。然而事实并非如此。无论您设置什么 preserveTopology,它们都是大小的缓冲区,以包含具有相同值的位置数据和正常数据。所以当我之前说没有正常数据时,我的意思是这两个缓冲区,语义顶点和语义正常都从 v1/n1/v2/n2... 变为 v1/v2/.../(0.0, 0.0, 0.0)/(0.0, 0.0, 0.0)/... 我进入 mdlmesh 的缓冲区(在转移到场景套件之前)发现了同样的问题,所以问题一定是 initWithURL,而不是模型 i/o到scenekit桥。 </p>

<p>所以我认为默认的顶点描述符和缓冲区分配器一定有问题(因为我使用的是 nil)并开始尝试创建我自己的匹配这两种可能的数据格式。唉,经过多次尝试,我无法得到有效的东西。</p>

<p>关于我应该如何做到这一点的任何想法?如何为 MDLAsset 提供正确的 vertexDescriptor 和 bufferAllocator(我觉得这里 nil 应该没问题)以导入 .obj 文件?谢谢</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>一个包含顶点和法线的 obj 文件有顶点,用 v 线表示,法线用 vn 线表示,还有面,用 f 线表示。</p>

<p>v 和 vn 行将只是您期望的浮点值,而 f 行将是形式 -</p>

<p>f v0//n0 v1//n1 等</p>

<p>由于 OpenGL 和 Metal 不允许多重索引,您将看到顶点被复制的第一个效果。例如,</p>

<p>f 0//0 1//2 2//0</p>

<p>不能用作顶点缓冲区,因为它需要每个顶点不同的索引。所以典型的 OBJ 解析器必须创建新的顶点来允许人脸变成</p>

<p>f 0//0 1//1 2//2</p>

<p>保留拓扑选项对您没有帮助。它保留了网格的连通性和形状(不发生三角剖分,共享边保持共享),但它仍然对每个顶点组件强制执行单个索引。</p>

<p>一种解决方案是确保输出 OBJ 文件的工具在导出期间使用单一索引(如果可以的话)。</p>

<p>另一种选择,这不会立即解决问题,是提出在模型 I/O 级别支持多索引的请求。 SceneKit 仍然需要唯一索引,因为它必须能够渲染。</p>

<p>另一种选择是使用像 PLY 这样没有多重索引的格式。</p></p>
                                   
                                                <p style="font-size: 20px;">关于iOS 将 .obj 文件导入模型 I/O 而不复制顶点,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/36509005/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/36509005/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: iOS 将 .obj 文件导入模型 I/O 而不复制顶点