2016-01-20 87 views
4

我應該看到2個黃色三角形,但我什麼都看不到。Scenekit:自定義幾何不顯示

class Terrain { 

    private class func createGeometry() -> SCNGeometry { 

     let sources = [ 
      SCNGeometrySource(vertices:[ 
       SCNVector3(x: -1.0, y: -1.0, z: 0.0), 
       SCNVector3(x: -1.0, y: 1.0, z: 0.0), 
       SCNVector3(x: 1.0, y: 1.0, z: 0.0), 
       SCNVector3(x: 1.0, y: -1.0, z: 0.0)], count:4), 
      SCNGeometrySource(normals:[ 
       SCNVector3(x: 0.0, y: 0.0, z: -1.0), 
       SCNVector3(x: 0.0, y: 0.0, z: -1.0), 
       SCNVector3(x: 0.0, y: 0.0, z: -1.0), 
       SCNVector3(x: 0.0, y: 0.0, z: -1.0)], count:4) 
     ] 

     let elements = [ 
      SCNGeometryElement(indices: [0, 2, 3, 0, 1, 2], primitiveType: .Triangles) 
     ] 

     let geo = SCNGeometry(sources:sources, elements:elements) 

     let mat = SCNMaterial() 
     mat.diffuse.contents = UIColor.yellowColor() 
     mat.doubleSided = true 
     geo.materials = [mat] 


     return geo 
    } 

    class func createNode() -> SCNNode { 

     let node = SCNNode(geometry: createGeometry()) 
     node.name = "Terrain" 
     node.position = SCNVector3() 
     return node 
    } 
} 

我用它如下:

let terrain = Terrain.createNode() 
    sceneView.scene?.rootNode.addChildNode(terrain) 


    let camera = SCNCamera() 
    camera.zFar = 10000 
    self.camera = SCNNode() 
    self.camera.camera = camera 
    self.camera.position = SCNVector3(x: -20, y: 15, z: 30) 
    let constraint = SCNLookAtConstraint(target: terrain) 
    constraint.gimbalLockEnabled = true 
    self.camera.constraints = [constraint] 

    sceneView.scene?.rootNode.addChildNode(self.camera) 

我與非定製的幾何形狀的其他節點,我看到的。怎麼了?

回答

2

您的索引數組的大小元素大小不正確。它被推斷爲[Int]。你需要[CInt]

我打破了你的elements設置成:

let indices = [0, 2, 3, 0, 1, 2] // [Int] 
    print(sizeof(Int))    // 8 
    print(sizeof(CInt))    // 4 
    let elements = [ 
     SCNGeometryElement(indices: indices, primitiveType: .Triangles) 
    ] 

要獲得指數被擠得像預期的數組c,顯式聲明類型:

let indices: [CInt] = [0, 2, 3, 0, 1, 2] 

Custom SceneKit Geometry in Swift on iOS not working but equivalent Objective C code does進入更多細節,但它是針對Swift 1寫的,所以你必須做一些翻譯。

SCNGeometryElement(indices:, primitiveType:)似乎沒有記錄在任何地方,雖然它確實出現在標題中。

2

Hal Mueller相當正確,因爲涉及的索引必須是指定的類型,但應該注意的是,在最新版本的Swift語言中,此功能發生了顯着變化。值得注意的是,SCNGeometryElement(indices:, primitiveType:)現在在Swift 4中運行得非常好,我建議不要使用CInt,這對我不起作用。而應使用符合FixedWidthInteger協議的標準整數類型之一,即Int32。如果您知道網格中涉及的最大頂點數量,請使用可包含所有頂點的最小位數。

例子:

let vertices = [ 
     SCNVector3(x: 5, y: 4, z: 0), 
     SCNVector3(x: -5 , y: 4, z: 0), 
     SCNVector3(x: -5, y: -5, z: 0), 
     SCNVector3(x: 5, y: -5, z: 0) 
    ] 

    let allPrimitives: [Int32] = [0, 1, 2, 0, 2, 3] 
    let vertexSource = SCNGeometrySource(vertices: vertices) 
    let element = SCNGeometryElement(indices: allPrimitives, primitiveType: .triangles) 
    let geometry = SCNGeometry(sources: [vertexSource], elements: [element]) 

    SCNNode(geometry: geometry) 

這裏發生了什麼?

首先我們創建一個描述三維空間中點的數組verticesallPrimitives數組描述了這些頂點如何鏈接。每個元素都是來自vertices陣列的索引。由於我們使用的是三角形,因此應該以三個一組來考慮,每個角落一個。爲了簡單起見,我在這裏做了一個簡單的扁平廣場。然後我們使用所有頂點的原始數組以及使用allPrimitives數組的幾何元素創建一個幾何源,其語義類型爲vertices,並且還通知它們是三角形,因此它知道將它們分成三部分。然後這些可用於創建與我們初始化我們的SCNNodeSCNGeometry對象。

想一想,最簡單的方法是頂點源只存在於列出對象中的所有頂點。幾何元素僅用於描述這些頂點如何鏈接起來。這是SCNGeometry將這兩個對象組合在一起以創建最終的物理表示。