Jennifer Liu
Jennifer Liu

Reputation: 21

Physics object falls to infinity in SceneKit

I'm making an AR app that's a ball toss game using Swift's ARKit.

Click here for my repo

The point of the game is to toss the ball and make it land in the hat. However, whenever I try to toss the ball, it always appear to fall to infinity instead of landing in the hat or on the floor plane that I've created.

Here's the code for tossing the ball:

    @IBAction func throwBall(_ sender: Any) {

    // Create ball
    let ball = SCNSphere(radius: 0.02)
    currentBallNode = SCNNode(geometry: ball)
    currentBallNode?.physicsBody = .dynamic()
    currentBallNode?.physicsBody?.allowsResting = true
    currentBallNode?.physicsBody?.isAffectedByGravity = true

    // Apply transformation
    let camera = sceneView.session.currentFrame?.camera
    let cameraTransform = camera?.transform
    currentBallNode?.simdTransform = cameraTransform!

    // Add current ball node to balls array
    balls.append(currentBallNode!)

    // Add ball node to root node
    sceneView.scene.rootNode.addChildNode(currentBallNode!)

    // Set force to be applied
    let force = simd_make_float4(0, 0, -3, 0)
    let rotatedForce = simd_mul(cameraTransform!, force)
    let vectorForce = SCNVector3(x:rotatedForce.x, y:rotatedForce.y, z:rotatedForce.z)

    // Apply force to ball
    currentBallNode?.physicsBody?.applyForce(vectorForce, asImpulse: true)
}

And here's the physics body setting for the floor:

Look at below screenshot for get more idea.

enter image description here

Upvotes: 0

Views: 663

Answers (1)

Jennifer Liu
Jennifer Liu

Reputation: 21

Nevermind, I managed to resolve this by adding the following function:

    func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
    guard let planeAnchor = anchor as? ARPlaneAnchor, planeAnchor.center == self.planeAnchor?.center || self.planeAnchor == nil else { return }

    // Set the floor's geometry to be the detected plane
    let floor = sceneView.scene.rootNode.childNode(withName: "floor", recursively: true)
    let plane = SCNPlane(width: CGFloat(planeAnchor.extent.x), height: CGFloat(planeAnchor.extent.y))
    floor?.geometry = plane
}

Upvotes: 2

Related Questions