|
Comments
Did you read today's front page stories & breaking news?
SYS-CON.TV
|
Director Snow Problem
The Physics of Havok
By: Nik Lever
Sep. 8, 2004 12:00 AM
So here's the deal: you want to create a snowboarding game. You have three weeks to do it, it can't exceed 1MB, and it must work online on at least 80% of kids' PCs. So let's list the options open to us. That's going to be one short list: boot up your copy of Director MX 2004 and get started! Before we get our boots on and set off for a great half-pipe session on our favorite board, we're going to need some assets. Here at Catalyst, we use Lightwave 3D for 3D asset creation. For most games that you create using Shockwave 3D, you will benefit by controlling at least some of the interactions using Havok. This remarkable Xtra is a rigid body physics simulation. If that sounds like a complicated thing and your eyes are beginning to cloud over, then wake up, because this is one to try. Trust me on this; you need to know this stuff. It's tricky at first, but the results are nothing short of amazing and before long you will be creating physics-based games with the best of them. In the next few pages we will start with an introduction to physics simulations followed by an overview of Havok in particular. Finally, we will look at applying this to an actual snowboarding game that is available online. There's lots to learn, but once you have mastered the basics, you will find that Havok looks after things in your game that, even after weeks of complex coding, would otherwise never have looked right. What Is Rigid Body Physics? For most 3D worlds, the actual size of the world is not important. However, when you start playing with physics, size is very important. Units in Havok are, by default, expected to be in meters and kilograms. The usual value for the force of gravity is 10ms2 (meters per second squared), which means that if the object starts from being stationary, after one second it will be travelling at 10ms. If you have an object that is about a meter square and give it a weight of around 10 kilograms and then drop it from a height of 3 meters with a force of gravity of 10ms2, then the way it tumbles will be just how you anticipated; it will hit the floor in less than a second and bounce or tumble depending on settings that you apply to the object to initialize it. If, however, the object is 100 units square and is dropped from 300 units high with a similar gravitational force, then you may think that the speed is wrong; in actual fact, you are dropping a large warehouse from 300 meters in the sky, not a small crate (see Figure 1). The distance travelled is given by the formula d = vt + 1/2 at2 Because a rigid body physics simulation has to work at an alarming rate, it approximates a huge number of the calculations to speed up the processing. Nevertheless, you should never give a physics simulation more work to do than it needs. Suppose you are using a physics simulation to move a car that is made from 1200 polygons. The car will look beautiful, but the same motion can be achieved by using a very simple substitute for the car. Look at Figure 2, where we show a car and the proxy object that can be used by the physics simulation to move the car. The proxy contains less than 100 polygons, whereas the car contains several thousand. The technique is to make the proxy invisible, to let Havok move the proxy, and then to copy the transform matrix of the proxy to the actual visible car model. A rigid body simulation at some stage in the calculations gets down to examining each vertex and triangle in the object. If we can get these down, the performance will soar. A common problem with a physics simulation is the time interval used in allowing impossible things to happen. In Figure 3, we see a ball going straight through a wall when it should have bounced off. Havok knows nothing about your world in the way you imagine it. It does know about time. If the number of frames updated a second is 25 and Havok calculates the positioning of the ball just prior to hitting the wall at 1.0 seconds, then just 0.04 seconds later it calculates that the ball is happily on the opposite side of the wall from where it appeared just a short interval before. As far as Havok is concerned, that's okay. It doesn't "realize" that the ball passed through the wall, because in the time intervals where it does do calculations, the ball is found to be in an acceptable position. There is a way out of this problem that does not require a computer capable of displaying 200 frames a second. Instead, we tell Havok to calculate sub-steps. If we tell it to calculate three sub-steps, then the very different behavior illustrated to the right of Figure 3 will occur. Although only two screen updates occur, three additional intermediary calculations ensure that Havok is kept abreast of the situation. It is possible to adjust the number of sub-steps to suit your application. You should aim to use the minimum number of sub-steps that avoids physics errors. Each additional sub-step takes computational time; therefore, by minimizing the number you will get the optimum frame rate performance. Creating a Scene that Uses Havok For the snowboarding game, we had to use the second method to create physical information where we use the models within a 3D scene to define the physics information. In this case, you must create a blank Havok cast member using the Insert > Media Element > Havok Physics Scene menu option. It is very important that you establish the scale of the physics scene from the start; as we discussed earlier, scale controls how the simulation matches real world experience. Internally, the Havok physics simulation employs the metric system (i.e., the default unit is meters). A W3D cast member may have been created in any number of world units (meters, inches, feet, user, generic). The Havok Xtra interface can work with the same units as this W3D cast member. However, in order to perform the proper simulation, Havok Xtra must know the correspondence between the display (3D scene) units and the simulation units. You must provide a world-scaling factor when initializing the physical simulation. For example, if you designed a scene using inches, then you would supply a scaling value of 0.0254 (1 inch = 0.0254 meter). Be aware that any values in the scene (like gravity, rest length of springs, etc.) are interpreted as scene units rather than internal physics units. That means that a real-world gravity value of 9.81 meters/second2 would have to be set as 386.22 inches/sec2 if working in inches. You must also provide a collision tolerance parameter. This tolerance is used to determine when objects are touching (i.e., if they are closer than the tolerance). In general, higher collision tolerance values yield more stable simulations. However, setting too high a value could lead to noticeable gaps between stacked objects. So it is recommended that you set the collision tolerance to the highest value at which it does not visually affect the scene. Figure 4 shows how tolerance affects the positioning of objects that stack. If a scene consists of many objects in a room (crates, tables, chairs, etc.), a tolerance of around 0.1m should be fine. However, if the objects in the scene are dice on a table, a smaller tolerance - say 0.01m or less - is preferable. If the objects are cars or buildings, a higher tolerance applies. If no value is supplied, then the default tolerance of 0.1 is used. As a general rule of thumb, the tolerance value should be set to around 10% of the scaling factor used in the simulation. Collision tolerance is a value measured in scene units. That means that the scaling factor affects its actual value. havok.initialize() must be the first Havok function called or other Havok functions will have no effect. Defining the Physical Properties of Your Models If you have an object in your scene that needs to be part of the physics but you know will never move, then use havok.makeFixedRigidBody(modelName, isConvex). This function creates a fixed rigid body from a model of name modelName and adds it to the simulation. Fixed rigid bodies never move, but are still involved in collision detection. These are mostly used for scenery elements like walls. Fixed bodies do not have mass. Mass is a property that only makes sense for objects which are free to move. To set up the simplest Havok scene follow these steps. We will use Lingo to provide all the physical simulation information rather than a prepared HKE file.
Havok cast member 2 Tolerance 0.1 Time Step 0.03 Sub Steps 3 Scale 1.0 The scale is set to 1.0 because the geometry was created using meters as the scale. The tolerance is set to 0.1 of a meter. Try adjusting the tolerance and scale to see how it affects the scene. You could also try adjusting the gravity vector set in line 5 of Listing 1. Adding Keyboard Control As in many games we produce, the main work of the demo is in a main loop, which in this case is the enterFrame handler of the 3D sprite behavior '3D Behavior'. Listing 2 shows the script. Starting with line 2, we call a simple keyboard reader. This stores whether or not the arrow keys and the space key are currently pressed. The values are stored in the property variables leftkey, rightkey, upkey, downkey, and spacekey. In this world, there are two rigid bodies, the course and the sledge. Notice that the sledge has two strange spikes sticking up. These help handle situations where the sledge is inverted. Once the demonstration is complete we can make the sledge object invisible and replace it with a visible alternative. We did this for a popular game at www.pingu.net; the crazy sledging game uses Listing 3 to handle most of the behavior of the sledge. The proxy object being used to control the sledges regardless of the choice of character is exactly the one shown in Figure 7. A rigid body has many additional properties and methods. To find out the full details, consult the Havok documentation either from your CD or from the Web site given earlier. One property is used in line 4 of Listing 3 - the linear Velocity; think of it as speed. Since we are going downhill, the y value should decrease so the difference between the previous y position and the current y position should be positive if we do the calculation shown in line 5. If it is negative, then we are trying to sledge uphill so we can use this to inform the player that they are going in the wrong direction; the code between lines 8 and 18 handles this, in this case simply by forcing the sledge to stop so the user cannot go too far in the wrong direction. A Practical Example Line 21 is where we use Havok to control the motion of the sledge. Instead of simply moving the sledge we give it a nudge using the rigid body method 'applyAngularImpulse'. This uses a vector to apply rotational motion to the rigid body. In the example at line 21, we use the previously stored property variable pTurn to give a rotation in the y axis. The left and right keys are used to control the rotation while the up and down arrows control forward and back motion. Lines 27 and 28 show how this is achieved; again we use a method of the rigid body, applyImpulse, that takes a vector and applies a force defined by the vector. To move the sledge, we want the force for a forward motion to be along its z axis, so we first get the z axis of the sledge, called board in line 27. This is scaled up by a boost value that is increased or decreased in lines 14 to 18. The behavior of the sledge would be highly erratic if we left it at that, so we must dampen down the effect in a separate handler, dampenPhysics, which we will look at in the next section. Controlling the Results Another thing we need to check is whether or not we are upside down. In any simulation, this can happen. To do this, we use the dot product of the sledge's y axis with the default y axis (0, 1, 0). If this is less than 0.5, then we are currently upside down. Rather than react immediately to this, we simply update a counter. This lets us adjust how quickly we reset from such a situation. In lines 42 to 48, you can see that we allow a count of 20 before attempting a correction. To do the correction, we take a default transformation matrix, set the position of the matrix to the current sledge position, then move this up a little to ensure we are above the snow. Then we use, in line 46, the 'interpola-tingMoveTo' method of the rigid body. This takes 2 parameters, position and orientation, expressed as an angle axis list. If the rigid body can be moved without interpenetrating other rigid bodies in the scene then the body is moved; if not it remains unmoved. A Real World Example The Havok Xtra is a fantastic tool for creating high-quality online games. In this article, we covered the basics of using the control then moved on to some of the more complex ways you can control the simulations. Always remember that the most important starting point for a simulation that uses Havok is to either bring in your geometry scaled to meters, or set up the scaling parameters to suit your geometry. Okay, boots on, bindings fastened, let's get some air!
The source code for this article is online at www.sys-con.com/mx/sourcec.cfm. Reader Feedback: Page 1 of 1
Your Feedback
Latest Cloud Developer Stories
Subscribe to the World's Most Powerful Newsletters
Subscribe to Our Rss Feeds & Get Your SYS-CON News Live!
|
SYS-CON Featured Whitepapers
Most Read This Week
Breaking Cloud Computing News
|
||||||||||||||||||||||||||||||||||||||||||||||||||||