2016-01-20 64 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:會導致更好的結果?