7

I've been playing with SceneKit, but I can't figure how to create a per vertex color geometry.

So to be more precise, I would like to do this : http://openglbook.com/chapter-2-vertices-and-shapes.html

Let me know if it's not clear

Thanks.

MonkeyDMat
  • 111
  • 2
  • 9
  • 1
    I think I found something interesting here [link](https://developer.apple.com/library/prerelease/ios/documentation/SceneKit/Reference/SceneKit_Constants/index.html#//apple_ref/doc/constant_group/Geometry_Semantic_Identifiers), the examples in SCNGeometrySource only talks about vertex position, normals and texCoord, but there is also a semantic for color – MonkeyDMat Sep 28 '15 at 11:26

1 Answers1

4

Pour info :

    sceneView = SCNView(frame: sceneContainer.bounds)
    sceneView.scene = SCNScene()
    sceneView.allowsCameraControl = true
    sceneView.autoenablesDefaultLighting = true
    sceneView.showsStatistics = true
    sceneView.backgroundColor = UIColor.darkGrayColor()

    self.sceneContainer.addSubview(sceneView)

    // Vertex
    let vertices: [SCNVector3] = [SCNVector3(0, 0, 0),
        SCNVector3(1, 0, 0),
        SCNVector3(0.5, 1, 0)]

    let vertexData = NSData(bytes: vertices, length: vertices.count * sizeof(SCNVector3))
    let vertexSource = SCNGeometrySource(data: vertexData, semantic: SCNGeometrySourceSemanticVertex, vectorCount: vertices.count, floatComponents: true, componentsPerVector: 3, bytesPerComponent: sizeof(Float), dataOffset: 0, dataStride: sizeof(SCNVector3))

    // Faces
    let indices: [Int32] = [0,1,2]

    let indexData = NSData(bytes: indices, length: sizeof(Int32) * indices.count)
    let indexElement = SCNGeometryElement(data: indexData, primitiveType: SCNGeometryPrimitiveType.Triangles, primitiveCount: indices.count / 3, bytesPerIndex: sizeof(CInt))

    // Normals
    let normals: [SCNVector3] = [SCNVector3(0, 0, 1),
        SCNVector3(0, 0, 1),
        SCNVector3(0, 0, 1)]

    let normalData = NSData(bytes: normals, length: sizeof(SCNVector3) * normals.count)
    let normalSource = SCNGeometrySource(data: normalData, semantic: SCNGeometrySourceSemanticNormal, vectorCount: normals.count, floatComponents: true, componentsPerVector: 3, bytesPerComponent: sizeof(Float), dataOffset: 0, dataStride: sizeof(SCNVector3))

    // Colors
    let colors: [SCNVector3] = [SCNVector3(1, 0, 0),
        SCNVector3(0, 1, 0),
        SCNVector3(0, 0, 1)]

    let colorData = NSData(bytes: colors, length: sizeof(SCNVector3) * colors.count)
    let colorSource = SCNGeometrySource(data: colorData, semantic: SCNGeometrySourceSemanticColor, vectorCount: colors.count, floatComponents: true, componentsPerVector: 3, bytesPerComponent: sizeof(Float), dataOffset: 0, dataStride: sizeof(SCNVector3))

    // Geometry
    let voxelGeometry = SCNGeometry(sources: [vertexSource, normalSource, colorSource], elements: [indexElement])
    let voxelMaterial = SCNMaterial()
    voxelMaterial.diffuse.contents = UIColor.whiteColor()
    voxelGeometry.materials = [voxelMaterial]

    voxelNode = SCNNode(geometry: voxelGeometry)
    voxelNode.position = SCNVector3(0, 0, 0)

    sceneView.scene?.rootNode.addChildNode(voxelNode)
MonkeyDMat
  • 111
  • 2
  • 9
  • 1
    There are some minor updates required for Swift 3. sizeof is replaced with MemoryLayout<___>.size and semantic argument can just be e.g. .color – James Aug 13 '17 at 10:43
  • 3
    Also you can hide a lot of the low level C-ish awfulness with extension functions in Swift for example ``` extension SCNGeometrySource { convenience init(data: [SCNVector3], semantic: SCNGeometrySource.Semantic) { let dataData = NSData(bytes: data, length: data.count * MemoryLayout.size) self.init(data: dataData as Data, semantic: semantic, vectorCount: data.count, usesFloatComponents: true, componentsPerVector: 3, bytesPerComponent: MemoryLayout.size, dataOffset: 0, dataStride: MemoryLayout.size) } } ``` – James Aug 13 '17 at 10:44