具有多边形的SCNGeometry作为primitiveType

试图找出如何创build一个多边形SCNGeometry作为primitiveType,我的目标是添加多边形节点作为一个球体节点的孩子,并使它看起来像地图工具包MKPolygon, 就像在这个例子 。

MKPolygon

我目前的代码是:

//Take an arbitrary array of vectors let vertices: [SCNVector3] = [ SCNVector3Make(-0.1304485, 0.551937, 0.8236193), SCNVector3Make(0.01393811, 0.601815, 0.7985139), SCNVector3Make(0.2971005, 0.5591929, 0.7739732), SCNVector3Make(0.4516893, 0.5150381, 0.7285002), SCNVector3Make(0.4629132, 0.4383712, 0.7704169), SCNVector3Make(0.1333823, 0.5224985, 0.8421428), SCNVector3Make(-0.1684743, 0.4694716, 0.8667254)] //Does polygon shape require indices? let indices: [Int] = [0,1,2,3,4,5,6] let vertexSource = SCNGeometrySource(vertices: vertices) let indexData = Data(bytes: indices, count: indices.count * MemoryLayout<Int>.size) //Note!!! I get compiler error if primitiveCount is greater than 0 let element = SCNGeometryElement(data: indexData, primitiveType: .polygon, primitiveCount: 0, bytesPerIndex: MemoryLayout<Int>.size) let geometry = SCNGeometry(sources: [vertexSource], elements: [element]) let material = SCNMaterial() material.diffuse.contents = UIColor.purple.withAlphaComponent(0.75) material.isDoubleSided = true geometry.firstMaterial = material let node = SCNNode(geometry: geometry) 

当像这样使用SCNGeometryElement时,我得到一个空的节点。

你有问题:

  1. SceneKit(和Metal)仅支持32位整数作为索引( 来源 )。 所以你的索引数组的types需要是[Int32]

  2. 对于多边形,SceneKit需要两条信息:多边形中的点数和顶点数组中点的索引。 从SCNGeometryPrimitiveTypePolygon (只存在于Objective-C中)的苹果文档中:

元素的data属性包含两个值序列。

  • 第一个序列的数值等于几何元素的primitiveCount值。 此序列中的每个值指定多边形基元中的顶点数。 例如,如果第一个序列是[5,3],则几何元素包含一个五边形,后面跟着一个三angular形。
  • 其余的数据是一系列顶点索引。 第一个序列中的每个条目指定第二个序列中相应的条目数。 例如,如果第一个序列包含值[5,3],则第二个序列包含五个五边形的索引,然后是三个三angular形的索引。

您需要将您的索引数组更改为:

 let indices: [Int32] = [7, /* We have a polygon with seven points */, 0,1,2,3,4,5,6 /* The seven indices for our polygon */ ] 

然后你可以设置primitiveCount为1(我们有一个多边形绘制),需要改变我们的缓冲区的大小

 let indexData = Data(bytes: indices, count: indices.count * MemoryLayout<Int32>.size) // Now without runtime error let element = SCNGeometryElement(data: indexData, primitiveType: .polygon, primitiveCount: 1, bytesPerIndex: MemoryLayout<Int32>.size)