0

In the scene, two 3d objects are not contacting with each other, but the function func physicsWorld(_ world: SCNPhysicsWorld, didBegin contact: SCNPhysicsContact) {} is called.

I use addItem() to add nodes in the scene

func addItem(hitTestResult: ARHitTestResult) {
        if let selectedItem = self.selectedItem {
            let scene = SCNScene(named: "art.scnassets/\(selectedItem).scn")
            let node = (scene?.rootNode.childNode(withName: selectedItem, recursively: false))!

            let transform = hitTestResult.worldTransform
            let thirdColumn = transform.columns.3
            node.position = SCNVector3(thirdColumn.x, thirdColumn.y, thirdColumn.z)


             node.physicsBody = SCNPhysicsBody(type:.dynamic, shape: SCNPhysicsShape(node: node, options: nil))


            node.physicsBody?.isAffectedByGravity = false


            node.physicsBody?.categoryBitMask = BitMaskCategory(rawValue: selectedItem)!.maskValue


            node.physicsBody?.contactTestBitMask = BitMaskCategory.mug.maskValue


            self.sceneView.scene.rootNode.addChildNode(node)
        }
    }


enum BitMaskCategory: String {

    case mug, banana, cup, vase

    var maskValue : Int {
        switch self {
        case .mug: return 1
        case .banana: return 2
        case .cup: return 3
        case .vase: return 4

        }
    }
}

As soon as I tap the screen and add two nodes(cup and mug) in the scene, these two nodes start to move away from each other. They are repelling each other, even though they are not contacting with each other.

Thanks.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
FYY
  • 37
  • 6
  • To debug collisions or contacts, you need to use the debug feature. sceneView.debugOptions = .showPhysicsShapes This will show you whether the physic shapes are larger than your visible rendered node. This usually occurs when you let SceneKit approximate the shape after importing a dae. – Clay Jan 13 '18 at 20:58

1 Answers1

1

The best way to debug collisions & contacts of physicsBodies is to use:

 sceneView.debugOptions = .showPhysicsShapes

In your code above you selected nil for physic Shape:

 node.physicsBody = SCNPhysicsBody(type:.dynamic, shape: SCNPhysicsShape(node: node, options: nil))

This option allows scenekit to approximate the shape... usually with poor results when using imported dae models created in third party 3d modelling software.

I generally apply a basic primitive physics shape such as sphere or box to complex dae models instead of using the nil option.

Extra Understanding

If your model has concave parts, like say a tube... and it doesn’t need to be dynamic. You can use the following code to make sure the tube can allow objects to travel thru the inner pipe section.

tubeNode.physicsBody = SCNPhysicsBody(type: .static, shape: SCNPhysicsShape(geometry: geometry, options: [SCNPhysicsShape.Option.type: SCNPhysicsShape.ShapeType.concavePolyhedron]))

this is the result... as you can see the green lines represents the physicsBody. An object like a ball can now fall through the centre of the tube.

enter image description here

If the object needs to dynamic, concave is not available... the code below you can set the option to convexHull on dynamic body.

 tubeNode.physicsBody = SCNPhysicsBody(type: .dynamic, shape: SCNPhysicsShape(geometry: geometry, options: [SCNPhysicsShape.Option.type: SCNPhysicsShape.ShapeType.convexHull]))

enter image description here

So a ball dropped above will sit on top of the tube and not pass thru the centre of the tube.

Clay
  • 1,721
  • 2
  • 10
  • 18
  • Thank you for your advice. I tried `self.sceneView.debugOptions = .showPhysicsShapes` and `node.physicsBody = SCNPhysicsBody(type:.dynamic, shape: SCNPhysicsShape(node: node, options:[SCNPhysicsShape.Option.type: SCNPhysicsShape.ShapeType.concavePolyhedron]))`. In the scene, the actual physics shape of a node is way bigger than the node in the scene. How can I fix it? Thanks – FYY Jan 15 '18 at 12:34
  • You can create basic shape type like SCNBox at the size you want and then apply it to the physicsBody(type.dynamic, shape: Box). You can also scale the physicsBody shape [update scnphysicsbody when scaling scnnode](https://stackoverflow.com/questions/48153416/update-scnphysicsbody-when-scaling-scnnode/48160307#48160307) – Clay Jan 15 '18 at 12:47