objective-c - 将MDLMesh划分为多个SCNGeometry

标签 objective-c swift scenekit

我有一个 .obj 文件,其中包含 3D 模型,分为多个较小的网格,例如正面和背面。
我的目标是将此文件加载到 SceneKit View 中并与模型的不同部分进行交互,为它们着色、选择它们、隐藏它们或单独移动它们。

我能够将文件加载到 MDLAsset 中,其中包含 MDLMesh,它本身包含所有子网格作为 MDLSubmesh

要显示加载的模型,我必须将 MDLMesh 转换为 SCNGeometry
基本方法是调用 SCNGeometry GeometryWithMDLMesh:(MDLMesh *)mdlMesh。这工作正常,SCNGeometry包含不​​同的SCNGeometryElements

但是,当将其转换为场景套件几何体时,MDLSubmesh 中的许多信息都会丢失,并且我与不同子网格体交互的能力非常有限。

如果我将所有 MDLSubmesh 单独转换为 SCNGeometry,那就太理想了。我尝试了两种不同的方法:

  1. 我尝试对每个子网格体使用[MDLMes newSubdividedMesh: aMesh submeshIndex: i subdivisionLevels:0]。然后我用它们创建了 SCNGeometry
    问题是 SceneKit 没有按方面渲染场景。几何体正常工作,但光线未应用于模型,这在我转换整个 MDLMesh 时有效。

从每个子网格生成一个新的网格:

for (NSInteger i = 0; i < [[mesh submeshes] count]; i++) {
    MDLMesh *submesh = [MDLMesh newSubdividedMesh:mesh submeshIndex:i subdivisionLevels:0];
    SCNGeometry *geometry = [SCNGeometry geometryWithMDLMesh:submesh];           
    SCNNode *subNode = [SCNNode nodeWithGeometry:geometry];          
    [node addChildNode:subNode];
}

使用这种方法得到的渲染结果rendering with subdivided meshes当转换整个 MDLMesh rendering the whole mesh 时。请注意使用上述代码进行第一次渲染时缺少的灯光效果。

  • 第二种方法是使用 SCNGeometry GeometryWithSources:elements: 方法生成 SCNGeometry。尽管我怀疑这是“正确”的方法,但这就是我尝试过的方法。

    • (SCNNode*) loadMDLMesh : (MDLMesh*) 网格与Submeshes: (bool) sub { 如果(子){ //生成场景套件节点 SCNNode * 节点 = [SCNNode 节点];

      //Generate a new mesh from each submesh
      for (NSInteger i = 0; i < [[mesh submeshes] count]; i++) {
          //Create the geometry element from the mdl sub mesh 
          SCNGeometryElement *element = [SCNGeometryElement geometryElementWithMDLSubmesh: [[mesh submeshes] objectAtIndex:i] ];
      
          //Create a geometry source from the index buffer
          MDLMeshBufferMap *map = [[[[mesh submeshes] objectAtIndex:i] indexBuffer] map];
      
          SCNGeometrySource *source = [SCNGeometrySource geometrySourceWithVertices:[map bytes] count:[[[mesh submeshes] objectAtIndex:i] indexCount]];
      
          //Create the SCNGeometry from the source and the element
          SCNGeometry *subMesh = [SCNGeometry geometryWithSources:[NSArray arrayWithObject:source] elements:[NSArray arrayWithObject:element]];
      
          //Update the name
          subMesh.name = [[[mesh submeshes] objectAtIndex:i] name];
      
          //Create a subnode and add it to the object node
          SCNNode *subNode = [SCNNode nodeWithGeometry:subMesh];
      
          [node addChildNode:subNode];
      }       
      
      return node;
      
      } else {
      return [SCNNode nodeWithMDLObject:mesh];
      }
      
  • 不幸的是,应用程序因错误访问异常而崩溃。

    正如人们所看到的,我在开发 Objective-C 方面没有那么丰富的经验。任何有助于修正我的想法或分割网格的不同方法的帮助都会很棒。

    谢谢。

    最佳答案

    [重新发布评论作为答案,因为它似乎提供了一个可行的解决方案]

    我看起来你在使用 +newSubdividedMesh:submeshIndex:subdivisionLevels: 时缺少法线从子网格构建新的网格。也许-initWithVertexBuffer:vertexCount:descriptor:submeshes:会带来更好的结果吗?

    关于objective-c - 将MDLMesh划分为多个SCNGeometry,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34897721/

    相关文章:

    ios - 如何为 cocos2d 应用设置单元测试?

    ios - 我可以将 Touch ID 弹出窗口中的操作名称从 "Enter password"更改为 "Enter passcode"吗?

    ios - 为什么我的 initWithNibName 方法返回一个 nil View ?

    ios - 首次启动时填写数据库核心数据的最佳方式是什么

    swift - 使用 SceneKit (SCNView) 显示统计信息(Swift 4/iOS 11 beta)

    ios - Scene kit 中的 3D 游戏开发?

    ios - ARKit 2 中的场景切换

    ios - ViewDidLoad 的随机图像生成器

    ios - 快速 UIActivityIndi​​catorView 而 NSURLConnection

    ios - 在 Swift 中从 UIButton 转到 ViewController