0
votes

When applying a force on a dynamic body, it seems that this force won't be persistent even if impulse is set at false.

I have a sphereNode with a physicsBody : dynamic, mass=1 and damping=0. World gravity is set at (0,0,0).

If I apply a force in a gesture recognizer :

func Detected(sender: UILongPressGestureRecognizer) {

    if sender.state == UIGestureRecognizerState.Began {
        sphereNode.physicsBody!.applyForce(SCNVector3Make(1, 0, 0), impulse: false)
    }

    if sender.state == UIGestureRecognizerState.Ended {
        sphereNode.physicsBody!.clearAllForces()     
    }
}

Then the velocity goes to 0.0166 as if the force was applied only during one frame and stay constant unless I trigger the gesture again.

The only way to make it work as a true constant force is to call applyforce in the renderer loop but then the only difference with the non-impulse applyforce is a factor of 60. I don't think that is the expected behavior.

1

1 Answers

2
votes

I think that is how it's supposed to work.

You use an impulse when you want to instantaneously change a body's momentum. For example, you might use impulse to fire a ball from a cannon. Like a cannon, it's "fire and forget"; you call the method and the ball flies off until it hits something.

You use a force (impulse:NO) when you want to make a continuous effect. That is, it doesn't cause a continuous effect (otherwise there'd have to be API for enumerating and canceling individual continuous forces on each body), but it gives you a tool to use when you want to do something on every frame to create a continuous effect.

For example, you'd use a force if you want your spaceship to accelerate when you press a button, and keep accelerating until you release it. While the button is held down, just call applyForce every time your update method runs.

The impulse toggle does two things for the two cases:

  • As you've noticed, it changes the units of magnitude to be appropriate for each case.
  • When using impulse:NO, it delays evaluation until the end of the current frame cycle. So you can apply several different forces during one update, and when SceneKit simulated physics for the next frame, it'll apply the sum of the forces (unless you call clearAllForces first).