## Simple collision response

Member
Posts: 45
Joined: 2006.11
Post: #1
I had a difficult time finding a simple, elegant solution to a seemingly simple problem.
The position of a projectile, it's size, and it's velocity
The intersection point with the terrain it collided with
The normal at the intersection point of the terrain it collided with
The percentage of speed to lose after the bounce
What I wanted:
The resulting position and velocity of the projectile after it collides and bounces off the terrain.

Here was the eventual solution (still approximation, but ok)
N: terrain normal
P: projectile position
V: projectile velocity
NV: normalized projectile speed
I: intersection point (from center of the projectile)
distanceToTerrain: distance between P and I
speed: basically the length of V
size: size of projectile (a bounding sphere)
scale: velocity is scaled by scale after the bounce (so usually between 0.0 and 1.0 for a percentage speed loss after bounce)
V = (V + (N * -2)) * scale
NewNV = normalized V
P = (I - (NV * size)) + (NewNV * (speed - distanceToTerrain - size))

The second line warrants some explanation: The projectile has a size parameter. We just simplify all objects and consider them spheres, so the size may be actual size or a bounding sphere. First we find the actual intersection point, which takes into account the size of the projectile, then we go from that point in the direction of the new velocity. We scale this by the time left over after the projectile travels to the real intersection point to get our new position.

In my game, I have a mutator system which mutates projectiles for different things like gravity, hovering, wind resistance, spring forces, etc.. Projectiles also have an update which adds the velocity to the position of the projectile. Most mutators will modify only speed, and then Update after all the mutators are done mutating the projectiles. I implemented the above algorithm as a mutator as well, but it mutates the position as well as the velocity, essentially doing an update operation at the same time (the other alternative was to place the projectile behind the intersection point so that the next projectile update operation would put it where it was supposed to go). Therefor, you must be careful not to double update. Apply this mutator after the other mutators have been processed, and without a separate update operation. (although I suppose separate Move and Update operations would be better so that you could have animation considerations in Update and just update the position in Move).

Comments? Inaccuracies? Inefficiencies? Let me know.

Jeremy Bell
WolverineSoft Project Coordinator
http://www.umich.edu/~wsoft
Moderator
Posts: 869
Joined: 2003.01
Post: #2
Collisions are tricky, especially the part what you do with the position of the point.

A good approximation is to leave the position alone for a bouncy collision. This will guarantee that your projectile does not cross the plane you are colliding with. If you move the position elsewhere than onto the collision plane, you *should* do another collision check to make sure that the extrapolated position would not cause any side effects to happen.

If you move the point anyway, you should move it onto the plane along the velocity vector, not the plane normal. That would be "I" un your case.

For sticky collisions, you probably want to move the projectile onto the plane, but in that case it is no problem, since it will stay put.

Generally, you should decide what kind of "mutators" you want to use. It is a good idea to restrict to impulse or force based mutators only, or to at least apply them at the right time.

My general, conventional, sim loop looks like this:
1. Apply forces
2. Integrate forces for new velocity
3. Integrate velocity for new position
4. Do collision detection
4a. Apply impulse of collisions, compute new velocity, possibly tweak positions.

There is two parts of effectors in this loop: at step 1, which are the regular things like gravity, springs, and damping, and at step 4, which are the things changing the impulse of the objects directly, I like to call this reactive effects (as opposed to active effects for step 1).

This approach comes in handy when you use some other integration scheme, like Verlet integration. In that case you don't really have velocities for your objects, but there are a few neat tricks with it.

At last: I'd do the following for projectile bounces:
e: elasticity of the collision (usually [0.0..1.0])
f: friction (sliding friction, if you want)
N: plane normal
V0: initial projectile velocity
V1: final projectile velocity
subscript (n): component parallel to n
subscript (p): component perpendicular to n

V0n = V0.projectOn(N)
V0p = V0 - V0n
V1 = -V0n*e + V0p*f
if no sliding friction:
V1 = -V0n*e + V0p*e = (-V0n + V0p)*e

EDIT: Fixed myself

and with position fiddling:
P1 = I
Member
Posts: 45
Joined: 2006.11
Post: #3

What exactly do you mean by sliding friction? I'm not sure what that means in the context of a collision. I don't yet account for a collisions effect on the projectile's angular velocity.
Also, there is of course the option to place the projectile at I (or in my case back from I to take the size of the projectile into account). This does, however, put a break in the timeline, since at the end of that frame the projectile would not be at I, but past I in the direction of the new velocity vector. However, one reason it would still be good to put the position at I would be that if the projectile is going reasonably fast, the two frames that surround the actual collision most likely will be far away from I. While overall the illusion is good, Inserting a frame where the projectile is at I might serve to emphasize the location of the collision. My game has a large scale, and some projectiles have very large speeds relative to the surrounding area, so if you shoot at the terrain point blank, it appears like the projectile just disappears. Setting the position at I flashes the projectile, at least for one frame, at the point of collision. The short time dilation that this produces is not quite so noticeable. Of course, one can always just take the projectile's speed into account. If it has a high speed, place at I, if not, place it in the correct position past the collision point, and adjust the threshold until it looks good.

Jeremy Bell
WolverineSoft Project Coordinator
http://www.umich.edu/~wsoft
Member
Posts: 156
Joined: 2002.11
Post: #4
There's an article on http://www.gamasutra.com about physics and elastic collisions for a pool game. It's really worth a look.
Moderator
Posts: 869
Joined: 2003.01
Post: #5

What exactly do you mean by sliding friction? I'm not sure what that means in the context of a collision. I don't yet account for a collisions effect on the projectile's angular velocity.

Never mind, the sliding friction only comes into the picture when you do collision response by applying a force to the projectile.

V1 = -V0n*e + V0p*e

is probably what you want. Sorry for being confusing.

JeroMiya Wrote:Also, there is of course the option to place the projectile at I (or in my case back from I to take the size of the projectile into account). This does, however, put a break in the timeline, since at the end of that frame the projectile would not be at I, but past I in the direction of the new velocity vector.

In that case, you have your integration backwards. The position update should be the last thing in your simulation step (or frame, if you like), unless you use implicit Euler integration, which, while improving stability somewhat, can be a pain.

Thinking about it, even then, your collision response should only be applied after the normal simulation step is done, e.g. after you calculated new velocity and position. Then, you take the pos & vel to fix them up without further changes.

JeroMiya Wrote:However, one reason it would still be good to put the position at I would be that if the projectile is going reasonably fast, the two frames that surround the actual collision most likely will be far away from I. While overall the illusion is good, Inserting a frame where the projectile is at I might serve to emphasize the location of the collision. My game has a large scale, and some projectiles have very large speeds relative to the surrounding area, so if you shoot at the terrain point blank, it appears like the projectile just disappears. Setting the position at I flashes the projectile, at least for one frame, at the point of collision. The short time dilation that this produces is not quite so noticeable. Of course, one can always just take the projectile's speed into account. If it has a high speed, place at I, if not, place it in the correct position past the collision point, and adjust the threshold until it looks good.

You should never knowingly place the particle behind the collision point, as that defeats the purpose of collision detection.

When your projectile hits, you could probably spawn some effect at I to show the hit, rather than relying on the projectile being seen.

Also, you might consider looking into Verlet integration. Since it stores the particle's previous position, it is quite easy to make a particle trail to emphasize its speed. Also available somewhere on gamasutra.com, in an article by Jakobson, something like "Advanced Character Physics".