Primitives in Scene Kit iOS Tutorial

SceneKit is a high-level framework for adding 3d graphics to your application. In this tutorial the primitive objects will be positioned in 3d-coordinates and each primitive is assigned a color. This tutorial is made with Xcode 10 and built for iOS 12.

Open Xcode and create a new Prjoject. Choose the Game template.

For product name, use IOS12SceneKitTutorial and then fill out the Organization Name and Organization Identifier with your customary values. Enter Swift as Language and SceneKit as Game Technology and choose Next.

Add a new File to the project, name it MyScene and make it a sublass of SCNScene

At the top of the MyScene.swift file import the SceneKit framework

import SceneKit

Next, add the required initializer methods inside the class.

class MyScene: SCNScene {
  
  override init() {
    super.init()
  }
  
  required init(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
  }
}

The custom code will be filled in at then end of the init method. First navigate to the GameViewController.swift file. The Game template has created some boilerplate code in this class. Delete all code inside the GameViewController class and add the viewDidLoad method

override func viewDidLoad() {
    super.viewDidLoad()
        
    let scnView = self.view as! SCNView
    scnView.scene = MyScene()
    scnView.backgroundColor = UIColor.black
}

A SCNView is created with the scene property set to MyScene and with a black background. Go back to the MyScene.swift file and add the following code at the end of the init method.

let plane = SCNPlane(width: 1.0, height: 1.0)
plane.firstMaterial?.diffuse.contents = UIColor.blue
let planeNode = SCNNode(geometry: plane)
        
rootNode.addChildNode(planeNode)

A plane object is created with a width and height of 1 unit. Scene Kit is node-based, which means the scene contains one rootNode and child nodes can be added to it. A node  is created containing the blue plane object and this node is added as a child node to the root node. Build and Run the project.

The front view of the plane is visible. It should be nice if some camera control is available and some lightning is applied to the scene. Go to GameViewController.swift file and add the following lines to the end of viewDidLoad

 scnView.autoenablesDefaultLighting = true
 scnView.allowsCameraControl = true

The default lightning of our scene is enabled and also the control of cameras on the simulator/device is allowed by using a one or two finger tap. Go back to the MyScene.swift file and add a new object at the end of the init method.

let sphere = SCNSphere(radius: 1.0)
sphere.firstMaterial?.diffuse.contents = UIColor.red
let sphereNode = SCNNode(geometry: sphere)
sphereNode.position = SCNVector3(x: 0.0, y: 3.0, z: 0.0)
    
rootNode.addChildNode(sphereNode)

A sphere is created with a radius of 1 unit. and a red color. The firstMaterial property is the type of material and the diffuse property is the base color of the material. With the SCNVector3 function the node can be positioned in 3 dimensions(x,y,z). Build and Run the project.

Two primitives are visible. The sphere is positioned above the plane, because the y-coordinate has value 3. The default coordinates of the plane is (0,0,0). Now add all other primitive objects at the end of the init method.

let box = SCNBox(width: 1.0, height: 1.0, length: 1.0, chamferRadius: 0.2)
box.firstMaterial?.diffuse.contents = UIColor.green
let boxNode = SCNNode(geometry: box)
boxNode.position = SCNVector3(x: 0.0, y: -3.0, z: 0.0)
    
rootNode.addChildNode(boxNode)
    
let cylinder = SCNCylinder(radius: 1.0, height: 1.0)
cylinder.firstMaterial?.diffuse.contents = UIColor.yellow
let cylinderNode = SCNNode(geometry: cylinder)
cylinderNode.position = SCNVector3(x: -3.0, y: 3.0, z: 0.0)
    
rootNode.addChildNode(cylinderNode)
    
let torus = SCNTorus(ringRadius: 1.0, pipeRadius: 0.3)
torus.firstMaterial?.diffuse.contents = UIColor.white
let torusNode = SCNNode(geometry: torus)
torusNode.position = SCNVector3(x: -3.0, y: 0.0, z: 0.0)
    
rootNode.addChildNode(torusNode)
    
let capsule = SCNCapsule(capRadius: 0.3, height: 1.0)
capsule.firstMaterial?.diffuse.contents = UIColor.gray
let capsuleNode = SCNNode(geometry: capsule)
capsuleNode.position = SCNVector3(x: -3.0, y: -3.0, z: 0.0)
    
rootNode.addChildNode(capsuleNode)
    
let cone = SCNCone(topRadius: 1.0, bottomRadius: 2.0, height: 1.0)
cone.firstMaterial?.diffuse.contents = UIColor.magenta
let coneNode = SCNNode(geometry: cone)
coneNode.position = SCNVector3(x: 3.0, y: -2.0, z: 0.0)
    
rootNode.addChildNode(coneNode)
    
let tube = SCNTube(innerRadius: 1.0, outerRadius: 2.0, height: 1.0)
tube.firstMaterial?.diffuse.contents = UIColor.brown
let tubeNode = SCNNode(geometry: tube)
tubeNode.position = SCNVector3(x: 3.0, y: 2.0, z: 0.0)
    
rootNode.addChildNode(tubeNode)

Build and Run the Project. All primitives are positioned in the scene and they are all visible.

You can download the source code of the IOS12SceneKitTutorial at the ioscreator repository on Github.