Solving Billiard Shot Impulse Trajectory

Post Reply
tkefauver
Posts: 10
Joined: Fri Jul 19, 2013 11:32 pm

Solving Billiard Shot Impulse Trajectory

Post by tkefauver »

I'm using bullet to make a pool simulator and need to accurately simulate shots that are humanly possible. To find the impulse to apply to the cue ball I use the locations of the object ball, pocket center and cue ball.

Image

In situations where the motion path of the cue ball is similar to the object ball (a hit angle near 180 degrees), everything works fine and the object ball sinks in the pocket. But it seems that the more angular the shot path is, the greater the margin of error is for the impulse I'm generating. I've tried many things to fix this: adjust the ball's collision margin, scaling the world larger, turning off friction and restitution and lots of others but nothing seems to changes this behavior.

Here are the relevant bits of my code:

Code: Select all

//assume p = pocket center, b = object ball center, c = cue ball center

//first find the position of the ghost ball, ie the target point of collision for the cue ball
btVector3 ghostPos = b+(b-p).normalize()*(2.0f*BALL_RADIUS);

//then use the normal between the ghostball and cue ball as the impulse, scaled by the shots total distance
btVector3 cueImpulse = (ghostPos-c).normalize()*((p.distance(b)+ghostPos.distance(c))*HIT_RATIO);

//finally apply the impulse to the cueball's center of mass (using general form of applyImpulse to later use rel_pos for english
cueBallBody->applyImpulse(cueImpulse,btVector3());
Hopefully that's enough info. I've been struggling with this bug for a looong time and now this very large project I've been working on for almost two years is contingent on solving this problem! Even if you don't see what's wrong with my code, but have an alternative strategy for finding the impulse - I would LOVE to hear it because I'm afraid I don't have anymore ideas.
tkefauver
Posts: 10
Joined: Fri Jul 19, 2013 11:32 pm

Re: Solving Billiard Shot Impulse Trajectory

Post by tkefauver »

After more reading I'm starting to think this may have something to do with what coordinate space my impulse is being calculated from. I know applyImpulse uses a world-space vector and I'm not sure if my calculation is in world space.

If that jogs anybodies circuits PLEEEEEEASE give me a suggestion even if you don't know the exact answer to my problem. It may be enough for something to click with me!
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: Solving Billiard Shot Impulse Trajectory

Post by drleviathan »

I think I've found the source of your inaccuracies. There is a bug in btRigidBody::applyImpulse() -- it does not compute the correct linear velocity when the impulse is imparted at a position that is offset from the RigidBody's center of mass, instead it applies the FULL impulse at the center. I've submitted a pull request for code that fixes the problem here: https://github.com/bulletphysics/bullet3/pull/272

I discovered this problem when tracking down an instability in a custom constraint that relies on correct behavior of applyImpulse(). When I fixed the bug my instability problems went away.
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: Solving Billiard Shot Impulse Trajectory

Post by drleviathan »

I take it back, there was no bug in btRigidBody::applyImpulse(). The logic makes sense in the special case where I "discovered" the bug, but not in general. I closed the pull request that I had created.

However, it turns out that when applyImpulse() is used to apply a unit of impulse at an offset actually introduces more energy into the system than the same impulse applied at the center of mass. This struck me as odd at first since it was the same amount of "poke", however after thinking about it some more I've decided that there is no paradox. The units of momentum are not the same as energy so the burden of conserving energy relies on the code that computed the amount of impulse to apply.
Post Reply