2016-01-20 60 views
1

我有一个.OBJ文件含有的3D模型,分割成多个较小的网格,例如前面和后面。
我的目标是这个文件加载到SceneKit查看和与模型的不同部分进行交互,对它们上色,选择它们,隐藏,或单独移动它们。划分MDLMesh成多个SCNGeometry

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

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

但是,在将其转换为Scene Kit Geometry时,会丢失MDLSubmesh中的大量信息,并且我与不同子网格进行交互的能力非常有限。

,如果我将所有的MDLSubmeshSCNGeometry单独这将是理想的。我已经尝试了两种不同的方法:

  1. 我试图用[MDLMes newSubdividedMesh: aMesh submeshIndex: i subdivisionLevels:0]为每个子网格。然后我创建了SCNGeometry
    问题是SceneKit没有渲染场景aspected。几何形状是工作正常但是指示灯没有被应用到模型,东西,当我转换了整个MDLMesh工作。

    //Generate a new mesh from each submesh 
        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渲染和转换的整个MDLMeshrendering the whole mesh时。用上面的代码注意第一次渲染时缺少的灯光效果。

  2. 第二种方法是用SCNGeometry geometryWithSources:elements:方法生成SCNGeometry。虽然我怀疑这是做这件事的“正确”方式,但这是我的尝试。

    - (SCNNode*) loadMDLMesh : (MDLMesh*) mesh withSubmeshes: (bool) sub 
    { 
        if (sub) 
        { 
         //Generate a scene kit node 
         SCNNode * node = [SCNNode node]; 
    
         //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的经验。任何帮助解决我的想法或不同的方法来细分网格将是很好的。

谢谢。

+0

它看起来像你使用'+ newSubdividedMesh时失踪法线:submeshIndex:subdivisionLevels:'打造从子网一个新的网格。也许'-initWithVertexBuffer:vertexCount:descriptor:submeshes:'会带来更好的结果吗? – mnuages

+0

非常感谢,这解决了我的问题 – orangenkopf

回答

1

我看起来像你使用+newSubdividedMesh:submeshIndex:subdivisionLevels:时建立从子网一个新的网格缺少法线[再张贴作为回答,因为它似乎它提供了一个解决方案的工作意见。也许-initWithVertexBuffer:vertexCount:descriptor:submeshes:会导致更好的结果?