2

I am pretty new to Swift, and SceneKit, and my current problem is that the custom shape I am trying to create is not showing up, even though the primitive shapes in the framework show up fine.

I have been following the tutorial from https://www.raywenderlich.com/1261-scene-kit-tutorial-with-swift-part-1-getting-started.

I have also checked out the answer on SO: SceneKit – Custom geometry does not show up. I have looked at other answers on here but none work for me.

Here is my code:

import UIKit
import SceneKit
import QuartzCore

class GameViewController: UIViewController {
    var scnView: SCNView!
    var scnScene: SCNScene!
    var cameraNode: SCNNode!

    override func viewDidLoad() {
        super.viewDidLoad()
        setupView()
        setupScene()
        setupCamera()
        let lightNode0 = SCNNode()
        lightNode0.light = SCNLight()
        lightNode0.light!.type = .omni
        lightNode0.position = SCNVector3(x: 0, y: 10, z: 10)
        scnScene.rootNode.addChildNode(lightNode0)

        let lightNode1 = SCNNode()
        lightNode1.light = SCNLight()
        lightNode1.light!.type = .omni
        lightNode1.position = SCNVector3(5, -10, 0)
        scnScene.rootNode.addChildNode(lightNode1)
        spawnShape()
    }

    func shouldAutorotate() -> Bool {
        return true
    }

    func prefersStatusBarHidden() -> Bool {
        return true
    }
    func setupView() {
        scnView = self.view as! SCNView
        // 1
        scnView.showsStatistics = true
        // 2
        scnView.allowsCameraControl = true
        // 3
        scnView.autoenablesDefaultLighting = true
    }
    func setupScene() {
        scnScene = SCNScene()
        scnView.scene = scnScene
    }

    func setupCamera() {
        // 1
        cameraNode = SCNNode()
        // 2
        cameraNode.camera = SCNCamera()
        // 3
        cameraNode.position = SCNVector3(x: 0, y: 0, z: 15)
        // 4
        scnScene.rootNode.addChildNode(cameraNode)
    }

And here is the function that produce the custom shape:

    func spawnShape() {
        // 1
        var geometry:SCNGeometry
        let positions = [
            SCNVector3(-2, 1.5, 0), //0
            SCNVector3(-2, 1.5, 0), //1
            SCNVector3(2, -1.5, 0), //2
            SCNVector3(2, 1.5, 0), //3
            SCNVector3(-2, 1.5, 0.4), //4
            SCNVector3(2, 1.5, 0.4) //5
        ]
        let source = SCNGeometrySource(vertices: positions)
        let indices:[CInt] = [
            0, 2, 1,
            0, 3, 2,
            0, 4, 5,
            0, 5 ,3,
            4, 1, 2,
            4, 2, 5
            ]
        let element = SCNGeometryElement(indices: indices, primitiveType:.triangles)

        // 4
        geometry = SCNGeometry(sources: [source], elements: [element])
        let geometryNode = SCNNode(geometry: geometry)

        // 5
        scnScene.rootNode.addChildNode(geometryNode)
    }
}
Andy Jazz
  • 49,178
  • 17
  • 136
  • 220
Anh Trần
  • 83
  • 1
  • 1
  • 7
  • How about check the size of `geometryNode` in function `spawnShape()`? I am afraid it is zero. – sakiM Sep 27 '18 at 02:05
  • sakiM how can I tell if my geometryNode is 0? It would be the case if geometry is null but geometry is not null – Anh Trần Sep 27 '18 at 04:41
  • I found out that my object was black and background was black so I can not see anything. But I looked through other code and tutorials and notice that they don't need to change the color or calculating the surface normal of an object to make it appear not black, the function will do it for you with the vertices input I believe. But I still want to try and add surface normal to it, I just don't know how. Any help? – Anh Trần Sep 28 '18 at 02:20

1 Answers1

1

Try my light-weighting code (macOS version for quick testing).

It's working:

import SceneKit

class GameViewController: NSViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let scene = SCNScene()
        let cameraNode = SCNNode()
        cameraNode.camera = SCNCamera()
        scene.rootNode.addChildNode(cameraNode)
        cameraNode.position = SCNVector3(x: 0, y: 0, z: 3)

        let geometry: SCNGeometry?
        let positions = [
            SCNVector3(0, 1, 0),
            SCNVector3(-0.5, 0, 0.5),
            SCNVector3(0.5, 0, 0.5),
            SCNVector3(0.5, 0, -0.5),
            SCNVector3(-0.5, 0, -0.5),
            SCNVector3(0, -1, 0),
        ]
        let source = SCNGeometrySource(vertices: positions)
        let indices: [UInt32] = [
            0, 1, 2,
            2, 3, 0,
            3, 4, 0,
            4, 1, 0,
            1, 5, 2,
            2, 5, 3,
            3, 5, 4,
            4, 5, 1
        ]
        let element = SCNGeometryElement(indices: indices, primitiveType:.triangles)
        geometry = SCNGeometry(sources: [source], elements: [element])
        geometry!.firstMaterial?.diffuse.contents = NSColor.red
        let geometryNode = SCNNode(geometry: geometry)
        scene.rootNode.addChildNode(geometryNode)

        let scnView = self.view as! SCNView
        scnView.scene = scene
        scnView.allowsCameraControl = true
        scnView.autoenablesDefaultLighting = true
        scnView.backgroundColor = NSColor.black
    }
}
Andy Jazz
  • 49,178
  • 17
  • 136
  • 220