8

我应该看到 2 个黄色三角形,但我什么也没看到。

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)

我得到了我看到的具有非自定义几何的其他节点。怎么了?

4

2 回答 2

7

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)

这里发生了什么事?

vertices首先,我们在三维空间中创建一个描述点数组。该allPrimitives数组描述了这些顶点是如何连接起来的。每个元素都是vertices数组中的一个索引。由于我们使用的是三角形,因此应该以三个为一组进行考虑,每个角一个。为简单起见,我在这里做了一个简单的平面正方形。然后我们创建一个几何源,其语义类型vertices使用所有顶点的原始数组,并使用该allPrimitives数组创建一个几何元素,同时通知它它们是三角形,因此它知道将它们分组为三个。然后可以使用这些来创建SCNGeometry我们初始化SCNNode.

一个简单的考虑方法是,顶点源的存在只是为了列出对象中的所有顶点。几何元素的存在只是为了描述这些顶点是如何连接起来的。它将SCNGeometry这两个对象组合在一起以创建最终的物理表示。

于 2017-09-30T09:39:55.513 回答
4

注意:请参阅 Ash 的回答,对于现代 Swift 来说,这是一种比这个更好的方法。

您的索引数组有错误的大小元素。它被推断为[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]

iOS 上 Swift 中的自定义 SceneKit 几何图形不起作用,但等效的 Objective C 代码确实更详细,但它是针对 Swift 1 编写的,因此您必须进行一些翻译。

SCNGeometryElement(indices:, primitiveType:)似乎没有在任何地方记录,尽管它确实出现在标题中。

于 2016-01-24T02:49:55.670 回答