Skip to main content
GameDev.net gamedev.net
🔒 Locked

Ball physics. Please comment

Started by NotTaxes Jan 15, 2003 at 12:38 PM 4 replies 1.7k views
Original Post
NotTaxes
NotTaxes
Howdy, I'm trying to simulate a ball interacting with its environment, and have a couple of questions. Q1: How do I get the ball to 'roll' along an arbitrary terrain? Q2: How do I get the ball to accurately bounce off an arbitrary terrain? Q3: What is the correct way to calculate the correct collision angle off a surface. To show that I am not just posting in ignorance, here's what I'm currently doing. The ball has three vector properties. X,Y,Z for its position. dX,dY,dZ for its direction and aX,aY,aZ for its acceleration. In terms of Q1, I am constantly adding a gravity acceleration to the aY vector, which pulls the ball down. I can check for collision with the terrain no problem using radius coldet, and I can calculate the x/z gradient of the terrain at the collision point. Basically I add the gradient vector (?) to the acceleration vector and hope for the best. The problem is that when the terrain gets intensely deformed, this method breaks down because several parts of the ball are potentially touching the terrain. In terms of Q2: and Q3: (which are probably the same question anyhow), I have no problem with calculating WHEN a collision occurs with either the terrain or a flat surface (like a wall) on the terrain, but I can't seem to get the reflexion angle correct. To put this a bit more clearly: If the ball is travelling in 2d space, and is moving downwards at 45-degrees to the left, and hits a vertical wall, then the ball should reflect to move down and to the right at 45-degrees. This is fine assuming that the wall is infinitely tall. However, if the ball collides with the top corner of the wall (which can happen with finite walls), then the ball would bounce up and to the right at 45-degrees. In 2d simulations I can easilly check to see which part of the ball hit the wall (top, left, bottom, right, or a combination of two sides) to get the correct reflection. In 3d this gets a lot more complex and time consuming. Now, I could just check for a collision at the point on the balls surface that corresponds to center+radius along the direction of dx,dy,dz, which would give me a collision at the point of forward motion. Then I could 'bend' the dxdydz according to the gradient of the surface hit, but this doesn't cater for cases where the edge of the ball hits an object, which would mean that I could have the ball travelling through objects. Anyway, I'm a bit stuck at the moment. What I have is semi-working, but it doesn't work perfectly in all situations. Any help would be great. [edited by - Nottaxes on January 15, 2003 1:43:18 PM]
'Doing the impossible is kind of fun' - Walt Disney
Zipster
Zipster
quote:
In terms of Q1, I am constantly adding a gravity acceleration to the aY vector, which pulls the ball down. I can check for collision with the terrain no problem using radius coldet, and I can calculate the x/z gradient of the terrain at the collision point. Basically I add the gradient vector (?) to the acceleration vector and hope for the best. The problem is that when the terrain gets intensely deformed, this method breaks down because several parts of the ball are potentially touching the terrain.

The terrain will have the effect of dampening the effect of acceleration on the ball, but you can''t just add the two vectors together. The normal vector for the terrain should be used as a device to calculate the affective acceleration of the ball, i.e the force that alters the velocity. The "flatter" the terrain, the more it dappens downward acceleration. In other words, the greater the Y value of terrain normal, the more it slows down the ball. The same goes for the other axis. Now, since the Y value of this normal will actually represent the sin() of the pitch angle of the terrain. So as the terrain gets flatter, this value approaches 1, and as the terrain gets less flat, eventually turning into a straight down cliff, the value approahces 0. As you can imagine, this value can be used as a multiplier for your Y acceleration. If the terrain is flat, you want to multiply by (1 - value) to cancel out downard acceleration. If the terrain is a cliff, then (1 - value) is 1, meaning that the full acceleration is used.

It is important to apply this to all the other axis, because if the terrain isn''t flat, it doesn''t just move in the Y direction, but in X and Z directions as well. You simply have to determine whether your multiplier will be value or (1 - value). Just picture the normal, and decide which one makes sense for each axis.
NotTaxes
NotTaxes
OK, so if I modify the ball''s xz acceleration vector by the plane''s xz normal (or a multiplier thereof) I would get the correct xz acceleration (where the multiplier will give an indication of friction). Then I can add the y normal (omt) to the gravity and apply the result to the ball''s y acceleration.

Presumably I could just take the plane''s inverse y normal and multiply it by the ball''s acceleration to do an impact bounce (so that the new acceleration on the ball, at the moment of impact, does not include any gravity e.g. aY = aY * -n.y). This aught to result in a perfectly elastic, but otherwise accurate, bounce, yes?
'Doing the impossible is kind of fun' - Walt Disney
Zipster
Zipster
Actually, when I look back on my explanation, I can see that it was just plain sh*t! Given a friction-less surface, the angle won''t affect the gravitational acceleration anyway. It''s just that the flatter the surface, the faster the ball is move in the XZ direction to be able to make constant it''s height as a function of time. Yes, I remember it now. If you roll a ball down a friction-less incline at height h, and drop a ball from height h, both at the same time, then their heights will remain equal as they fall. Well, in order for this to be accomplished, the ball on the incline has to move to the right really damn fast because of the slope. The flatter the slope, the faster the ball has to move "to the side".

You''re completely correct when you say "or a multiplier" thereof, because friction makes all the difference.
Nypyren
Nypyren
First, I handle the gravity stuff exactly as you do: set aY or aZ (whatever your system) to a constant "down" number at the beginning of the frame. If there are no other forcefields, I never modify acceleration again in the frame.


Here's how I do ball physics:

For each triangle, find point of impact (if any). (toughest part)

Generate a vector in the direction from the center of the ball to the point of impact... this is your collision normal. It won't matter which direction it is or whether you normalize it or not.

Find out how much of the ball's velocity projects onto that vector (if you don't know how to do projection, look it up online)

Assuming the object you bumped into is immobile, you subtract TWICE the length of the projection-result from your velocity. This acts as if the wall/immobile object reflected 100% of your momentum back at you. It you have two moving objects with their own mass/velocity, this equation is much more complex.

Make the sound system make a satisfying "boing" or "ting" noise

You're done.

The tricky part is finding the point of collision, but it sounds like you have that almost all figured out.

Here's what you need:

Assuming you work with triangles, you need to find out if the ball is touching the "face" (the plane between the 3 sides), or if it is touching any of the sides, or if it is touching any of the vertices. obviously if one of these tests comes up positive, you don't need to check the others.

If you don't include the line/point tests, there will be gaps in your terrain (convex edges/points) where the ball can fall through.

[edited by - Nypyren on January 16, 2003 4:44:29 AM]

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.