Tricks of the Windows Game Programming Gurus:Playing God: Basic Physics Modeling

All ITKnowledge Source Code Search Tips Advanced Search |

| Tricks of the Windows Game Programming Gurus by Andre LaMothe Sams, Macmillan Computer Publishing ISBN: 0672313618 Pub Date: 09/27/99

Search this book:

Previous | Table of Contents | Next

#### Data Structures for Physics Modeling

One of the questions that I’m asked continuously (in addition to how to compile DirectX programs with VC++) is what data structures to use for physics modeling. There are no physics-data structures! Most physics models are based on the game objects themselves—you simply need to add enough data elements to your primary data structures to figure the physics out—get it? Nonetheless, you should keep track of the following parameters and values in any physics engine for the universe and objects:

  • Position and velocity of the object.
  • Angular velocity of the object.
  • Mass, frictional coefficient, and any other physical properties of the object.
  • Physics engine geometry for the object. This is simply a geometry that can be used for the physics calculations. You may use rectangles, spheres, or whatever, rather than the actual object geometry.
  • External universal forces such as wind, gravity, and so on.

Now it’s up to you to represent all these values with whatever structures or types are appropriate. For example, the realistic collision response demo used a model something like this:

Each Ball Object

    float x,y; // position

    float xv,yv; // velocity

    float radius; // guess?

    float coefficient_of_restitution; // just what it says

Of course the data was hidden a little in some internal arrays in each of the BOBs (blitter objects) that represented the balls, but the abstract data structure is what we’re interested in.

#### Frame-Based Versus Time-Based Modeling

This is the final topic I want to talk about since it’s becoming more and more important in 3D games. Thus far in the book, we have had a game loop that looks like Figure 13.44. We have been assuming that the game will run at a constant rate of R fps. If it doesn’t, then no big deal, everything will slow down on the screen. But what if you didn’t want things to slow down on the screen? What if you wanted a ship to move from a to b in two seconds no matter what the frame rate was? This is called time-based modeling.

Figure 13.44 The game loop you’ve learned to love.

Time-based modeling differs from frame-based modeling in that time t is used in all the kinematic equations that move objects. For example, in a frame-based game if you have the chunk of code:

    x = 0, y = 0;

    x = x + dx;

    y = y + dy;

and the game runs at 30 fps, then in 30 frames or 1 second, x,y will equal

    x = 30*dx;

    y = 30*dy;

If dx=1 and dy=0 then the object would move exactly 30 pixels in the x-direction. And this is fine if you can always guarantee a constant frame rate. But what if the frame rate drops to 10 fps? Then in 1 second, you will have:

    x = 10*dx = 10

    y = 10*dy = 0

x only changed one-third of what you wanted it to! If visual continuity is what you are going for then this is unacceptable. In addition, this can wreak havoc on a network game. In a network game you can either sync to the slowest machine and stay frame-based, or you can let all the machine free run and use time modeling, which is the more realistic and fair thing to do. I shouldn’t have to pay for someone else owning a 486 when I have a PIII 1000MHz.

To implement time-based motion and kinematics, you have to use time in all of your motion equations. Then, when it’s time to move objects, you have to test the difference in time from the last movement and use this as the input into your equations. Thus, as the game slows down a lot, it won’t matter because the time parameter will convey this and cause a larger motion. Here’s an example game loop:

    while(1)

    {

    t0 = Get_Time(); // assume this is in milliseconds

    // work, work, work

    // move objects

    t1 = Get_Time();

    // move all the objects

    Move_Objects(t1 – t0);

    // render

    Render();

    } // end while

With this loop we use the change in time or (t1-t0) as an input to the motion code. Normally there would be no input; the motion code would just move. Let’s assume that we want our object to move at 30 pixels per second, but since our time base is in milliseconds, or 1×10-3 seconds, we need to scale this:

    dx = 30 pixels/1 sec = .03 pixels/1 millisecond

Can you see where I’m going? Let’s write the motion equation for x:

    x = x + dx*t

Plugging everything in we get

    x = x +.03*(t1 – t0)

That’s it. If a single frame takes one second then (t1 – t0) will be 1000 milliseconds and the motion equation will equal

    x = x + .03*1000 = 30, which is correct!

On the other hand, if the time for this frame takes three milliseconds then the motion equation will look like:

    x = x + .03*3 = .09, which is also correct!

Obviously you need to use floating point values for all this to work since you are going to be tracking fractions of pixel motion, but you get the idea. This is so cool because even if your game starts bogging down hardcore due to rendering, the motion will stay the same.

As an example, check out `DEMO13_11.CPP|EXE`; it basically moves a little ship (with a shadow!) from left to right and allows you to alter the delay of each frame using the arrow keys to simulate processor load.

Notice that the ship moves at a constant rate. It may jump, but it will always travel a total distance of 50 pixels/sec no matter what the frame rate. As a test, the screen is 640 pixels wide, plus the off-screen overlap of 160 pixels, thus the entire travel is 800 pixels. Since the ship is traveling at 50 pixels/sec that means that it should take 800/50=16 seconds to make one pass. Try changing the delay and note that this is always true. If your game was designed to run at 60 fps and it slows to 15–30 then the jumping won’t be that apparent and the game will look the same, but less smooth. Without time modeling your game WILL slow down and look like it’s in slow motion—I’m sure you have seen this many times. :)

### Summary

I’m sure this chapter has been somewhat enlightening whatever your background is. It gave me a headache writing it! We covered a lot of ground and learned various ways to look at things. For example, we tried an ad hoc collision response algorithm that worked great for a ball bouncing off a rectangle. This technique is perfect for any kind of pong or breakout game. Then we looked more closely at the mathematics of reflection and derived the correct way to do it in general. This is the point of physics modeling in games—and you just learned how to do it.

Previous | Table of Contents | Next

Copyright © Macmillan Computer Publishing, Inc.

Products | Contact Us | About Us | Privacy | Ad Info | Home
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc. All rights reserved. Reproduction in whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.