0

Following this solution: Custom SceneKit Geometry and converted to Swift 3, the code became:

func drawLine() {

    var verts = [SCNVector3(x: 0,y: 0,z: 0),SCNVector3(x: 1,y: 0,z: 0),SCNVector3(x: 0,y: 1,z: 0)]

    let src = SCNGeometrySource(vertices: &verts, count: 3)
    let indexes: [CInt] = [0, 1, 2]

    let dat  = NSData(
        bytes: indexes,
        length: MemoryLayout<CInt>.size * indexes.count
    )
    let ele = SCNGeometryElement(
        data: dat as Data,
        primitiveType: .line,
        primitiveCount: 2,
        bytesPerIndex: MemoryLayout<CInt>.size
    )
    let geo = SCNGeometry(sources: [src], elements: [ele])

    let nd = SCNNode(geometry: geo)

    geo.materials.first?.lightingModel = .blinn
    geo.materials.first?.diffuse.contents = UIColor.red
    scene.rootNode.addChildNode(nd)

}

It work on simulator:

red line on simulator

But I got error on device:

/BuildRoot/Library/Caches/com.apple.xbs/Sources/Metal/Metal-85.83/ToolsLayers/Debug/MTLDebugRenderCommandEncoder.mm:130: failed assertion `indexBufferOffset(0) + (indexCount(4) * 4) must be <= [indexBuffer length](12).'

What is happening?

The entire code is here: Source code

Community
  • 1
  • 1
Yuri Natividade
  • 354
  • 2
  • 3

1 Answers1

2

I'm answering my own question because I found a solution that can help others.

The problem was on "indexes", 3 indexes won't draw 2 vertices. Must set 2 indexes for each vertice you want to draw.

This is the final function:

func drawLine(_ verts : [SCNVector3], color : UIColor) -> SCNNode? {

    if verts.count < 2 { return nil }

    let src = SCNGeometrySource(vertices: verts, count: verts.count )
    var indexes: [CInt] = []

    for i in 0...verts.count - 1 {
        indexes.append(contentsOf: [CInt(i), CInt(i + 1)])
    }

    let dat  = NSData(
        bytes: indexes,
        length: MemoryLayout<CInt>.size * indexes.count
    )

    let ele = SCNGeometryElement(
        data: dat as Data,
        primitiveType: .line,
        primitiveCount: verts.count - 1,
        bytesPerIndex: MemoryLayout<CInt>.size
    )

    let line = SCNGeometry(sources: [src], elements: [ele])

    let node = SCNNode(geometry: line)

    line.materials.first?.lightingModel = .blinn
    line.materials.first?.diffuse.contents = color

    return node
}

Calling:

scene.rootNode.addChildNode(
    drawLine(
        [SCNVector3(x: -1,y: 0,z: 0),
         SCNVector3(x: 1,y: 0.5,z: 1),
         SCNVector3(x: 0,y: 1.5,z: 0)] , color: UIColor.red
        )!
)

Will draw: enter image description here

Yuri Natividade
  • 354
  • 2
  • 3