title: How do I handle collision detection in Scenekit with Swift?
body: <p>I have been trying to set up a simple Scenekit scene with some physics so I could learn about how SCNPhysicsContactDelegate, categoryBitMask, collisionBitMask and the physicsWorld func work. Not sure if I need to set up a contactTestBitMask as well.</p>
  
  <p>Learning about contact detection sent me down a long path of bitwise operators and the concept of bit masking. Adding in binary is fun!  However, this is all still very foggy and I am trying to cobble together several tutorials I've found in both SpriteKit and SceneKit.  <a href="https://stackoverflow.com/questions/27372138/how-to-set-up-scenekit-collision-detection?rq=1">This is the most comprehensive</a> but it is in Obj-C and I don't understand it how to translate to Swift. </p>
  
  <p>Here is what I have created. Any insights would be much appreciated. Can you see what I have set up incorrectly?  I would like to have a simple Print statement occur when the red rolling ball hits the blue target.  The floor, ramp and target are .static, while the rolling ball is .dynamic. </p>
  
  <p><img src="https://i.stack.imgur.com/VbVK2.gif" alt="Animated Gif of Scene"></p>
  
  <pre><code>import UIKit
  import SceneKit
  
  
  class ViewController: UIViewController, SCNPhysicsContactDelegate {
      //category bit masks for ball node and target node
      // ball = 0001 -&gt; 1 and target = 0010 -&gt;2
      let collisionRollingBall: Int = 1 &lt;&lt; 0
      let collsionTarget: Int = 1 &lt;&lt; 1
  
  //declare variables
  var sceneView: SCNView!
  var cameraNode: SCNNode!
  var groundNode: SCNNode!
  var lightNode: SCNNode!
  var rampNode: SCNNode!
  var rollingBallNode: SCNNode!
  var targetNode: SCNNode!
  
  override func viewDidLoad() {
      super.viewDidLoad()
      //set up sceneview and scene. Define the physicsworld contact delegate as self
      sceneView = SCNView(frame: self.view.frame)
      sceneView.scene = SCNScene()
      sceneView.scene!.physicsWorld.contactDelegate = self
      self.view.addSubview(sceneView)
  
      //add floor
      let groundGeometry = SCNFloor()
      groundGeometry.reflectivity = 0
      let groundMaterial = SCNMaterial()
      groundMaterial.diffuse.contents = UIColor.greenColor()
      groundGeometry.materials = [groundMaterial]
      groundNode = SCNNode(geometry: groundGeometry)
  
      //add ramp
      let rampGeometry = SCNBox(width: 4, height: 1, length: 18, chamferRadius: 0)
      rampNode = SCNNode(geometry: rampGeometry)
      rampNode.position = SCNVector3(x: 0, y: 2.0, z: 1.0)
      rampNode.rotation = SCNVector4(1, 0, 0, 0.26)
  
      //add rolling ball
      let rollingBallGeometry = SCNSphere(radius: 0.5)
      let sphereMaterial = SCNMaterial()
      sphereMaterial.diffuse.contents = UIColor.redColor()
      rollingBallGeometry.materials = [sphereMaterial]
      rollingBallNode = SCNNode(geometry: rollingBallGeometry)
      rollingBallNode.position = SCNVector3(0, 6, -6)
  
      //add target box
      let targetBoxGeometry = SCNBox(width: 4, height: 1, length: 4, chamferRadius: 0)
      let targetMaterial = SCNMaterial()
      targetMaterial.diffuse.contents = UIColor.blueColor()
      targetBoxGeometry.materials = [targetMaterial]
      targetNode = SCNNode(geometry: targetBoxGeometry)
      targetNode.position = SCNVector3(x: 0, y: 0.5, z: 11.5)
      targetNode.rotation = SCNVector4(-1,0,0,0.592)
  
      //add a camera
      let camera = SCNCamera()
      self.cameraNode = SCNNode()
      self.cameraNode.camera = camera
      self.cameraNode.position = SCNVector3(x: 13, y: 5, z: 12)
      let constraint = SCNLookAtConstraint(target: rampNode)
      self.cameraNode.constraints = [constraint]
      constraint.gimbalLockEnabled = true
  
      //add a light
      let spotLight = SCNLight()
      spotLight.type = SCNLightTypeSpot
      spotLight.castsShadow = true
      spotLight.spotInnerAngle = 70.0
      spotLight.spotOuterAngle = 90.0
      spotLight.zFar = 500
      lightNode = SCNNode()
      lightNode.light = spotLight
      lightNode.position = SCNVector3(x: 0, y: 25, z: 25)
      lightNode.constraints = [constraint]
  
      //define physcis bodies
      let groundShape = SCNPhysicsShape(geometry: groundGeometry, options: nil)
      let groundBody = SCNPhysicsBody(type: .Static, shape: groundShape)
      groundNode.physicsBody = groundBody
  
      let rampShape = SCNPhysicsShape(geometry: rampGeometry, options: nil)
      let rampBody = SCNPhysicsBody(type: .Static, shape: rampShape)
      rampNode.physicsBody = rampBody
  
      let sphereShape = SCNPhysicsShape(geometry: rollingBallGeometry, options: nil)
      let sphereBody = SCNPhysicsBody(type: .Dynamic, shape: sphereShape)
      rollingBallNode.physicsBody?.categoryBitMask = collisionRollingBall
      rollingBallNode.physicsBody?.collisionBitMask = collsionTarget
      rollingBallNode.physicsBody = sphereBody
  
      let targetShape = SCNPhysicsShape(geometry: targetBoxGeometry, options: nil)
      let targetBody = SCNPhysicsBody(type: .Static, shape: targetShape)
      targetNode.physicsBody?.categoryBitMask = collsionTarget
      targetNode.physicsBody?.collisionBitMask = collisionRollingBall
      targetNode.physicsBody = targetBody
  
      //add nodes to view
      sceneView.scene?.rootNode.addChildNode(groundNode)
      sceneView.scene?.rootNode.addChildNode(rampNode)
      sceneView.scene?.rootNode.addChildNode(rollingBallNode)
      sceneView.scene?.rootNode.addChildNode(targetNode)
      sceneView.scene?.rootNode.addChildNode(self.cameraNode)
      sceneView.scene?.rootNode.addChildNode(lightNode)
  
  }
  
  func physicsWorld(world: SCNPhysicsWorld, didBeginContact contact: SCNPhysicsContact) {
  print("contact")
  
   //   let contactMask = contact.nodeA.categoryBitMask | 
  //contact.nodeB.categoryBitMask
  
      //if contactMask == collsionTarget | collisionRollingBall {
        //  print("The ball hit the target")
    //  }
  
  }
  
  override func didReceiveMemoryWarning() {
      super.didReceiveMemoryWarning()
      // Dispose of any resources that can be recreated.
  }
  
  
  }
  </code></pre>