Search code examples
iosswiftscenekitphysicsscnnode

Swift SceneKit: Why does it detect contact between nodes too early?


I am trying to build some project using SCNPhysicsContactDelegate, but it I found that it detects contact between my nodes too early. I need it to be 100% precise and correct. I am attaching screenshot of too early contact detection. There is my code for theirs physics bodies:

nodeA code:

        nodeA = SCNNode(geometry: SCNBox(width: 0.3, height: 0.3, length: 0.3, chamferRadius: 0.05))
        nodeA.position = SCNVector3(0, 3.3, 0)
        nodeA.geometry?.firstMaterial?.diffuse.contents = UIColor.red
        nodeA.physicsBody = SCNPhysicsBody.dynamic()
        nodeA.physicsBody?.physicsShape = SCNPhysicsShape(node: nodeA, options: nil)
        nodeA.physicsBody?.categoryBitMask = PhysicsCategories.nodeA
        nodeA.physicsBody?.contactTestBitMask = PhysicsCategories.nodeB
        nodeA.physicsBody?.isAffectedByGravity = false
        nodeA.name = "nodeA"
        nodeA.opacity = 0
        self.scene.rootNode.addChildNode(self.nodeA)

nodeB code: (nodeB already exists, so I am only adding physics body)

        nodeB.physicsBody = SCNPhysicsBody.kinematic()
        nodeB.physicsBody?.physicsShape = SCNPhysicsShape(node: nodeB, options: nil)
        nodeB.physicsBody?.categoryBitMask = PhysicsCategories.nodeB
        nodeB.physicsBody?.contactTestBitMask = PhysicsCategories.nodeA

contact function code:

        func physicsWorld(_ world: SCNPhysicsWorld, didBegin contact: SCNPhysicsContact) {
            scene.isPaused = true
        }

bad collision image

Could you please someone help me find the solution? I look forward to your hearings guys.

Thanks Jakub


Solution

  • I found the solution! These two lines caused imprecise contact detection:

    nodeA.physicsBody?.physicsShape = SCNPhysicsShape(node: nodeA, options: nil) and nodeB.physicsBody?.physicsShape = SCNPhysicsShape(node: nodeB, options: nil).

    The problem was that, when you create SCNPhysicsShape() with node attribute it is imprecise, but when you create it with nodes geometry it all works totally right and precise. In my case the solution looks like this(replace the problem lines by these lines):

    nodeA.physicsBody?.physicsShape = SCNPhysicsShape(geometry: SCNBox(width: 0.3, height: 0.3, length: 0.3, chamferRadius: 0.05), options: nil) and nodeB.physicsBody?.physicsShape = SCNPhysicsShape(geometry: SCNBox(width: 0.1, height: 0.5, length: 1, chamferRadius: 0), options: nil)