2016-01-20 85 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将这两个对象组合在一起以创建最终的物理表示。