1. Introduction to Game Physics with Box2D
2. Mathematics for Game Physics
Lecture 2.2: Digital Calculus
Ian Parberry
Dept. of Computer Science & Engineering
University of North Texas
2. Contents
• Euler and Verlet Integration
• Gauss-Seidel Relaxation
Chapter 2 Introduction to Game Physics with Box2D 2
3. Chapter 2 Introduction to Game Physics with Box2D 3
7. Euler Integration
This corresponds to Euler integration. Instead of
integrating the curve, we are summing over
discrete time-slices.
Chapter 2 Introduction to Game Physics with Box2D 7
8. Implementation
We implement this by storing each object’s
position, velocity, acceleration, and last move time.
D3DXVECTOR2 m_vP; //position
D3DXVECTOR2 m_vV; //velocity
D3DXVECTOR2 m_vA; //acceleration
int m_nLastMoveTime; //time of last move
We then update position and velocity once per frame.
int t = timeGetTime(); //current time in msec
int dt = t - m_nLastMoveTime; //frame time
m_vP += m_vV * dt; //update position
m_vV += m_vA * dt; //update velocity
m_nLastMoveTime = t; //update time
Chapter 2 Introduction to Game Physics with Box2D 8
10. But in a Game?
• We compute the distance moved in each
frame and accumulate all those distances to
get the total distances.
• We have to assume that the velocity is
constant within each frame.
• We end up with the following set of distances,
which is too small…
Chapter 2 Introduction to Game Physics with Box2D 10
11. Chapter 2 Introduction to Game Physics with Box2D 11
12. Velocity as a Continuous Function of Time
Chapter 2 Introduction to Game Physics with Box2D 12
13. Velocity as a Discrete Function of Time
Chapter 2 Introduction to Game Physics with Box2D 13
14. Verlet Integration
• Loup Verlet, 1951-
• Developed the concept that
is now called Verlet
integration for use in
particle physics simulation.
Chapter 2 Introduction to Game Physics with Box2D 14
15. Why Do We Care?
• There are mathematical reasons for using Verlet
integration instead of Euler integration when
simulating real particle systems.
• But what about in games? We don’t care so much
about reality.
• One useful feature of Verlet integration is that it
is easy to incorporate constraints, for example, to
fix lengths and angles.
• This means that Verlet integration makes it easier
to code soft-body animation including cloth and
ragdoll.
Chapter 2 Introduction to Game Physics with Box2D 15
18. Summary of Verlet Integration
Chapter 2 Introduction to Game Physics with Box2D 18
19. Compare and Contrast
Euler:
Verlet:
Chapter 2 Introduction to Game Physics with Box2D 19
20. Implementation
We implement this by storing each object’s position,
previous position, acceleration, and last move time.
D3DXVECTOR2 m_vP; //position
D3DXVECTOR2 m_vOldP; //previous position
D3DXVECTOR2 m_vA; //acceleration
int m_nLastMoveTime; //time of last move
We then update position and velocity once per frame.
int t = timeGetTime(); //current time in millisec
int dt = t - m_nLastMoveTime; //frame time
D3DXVECTOR2 vTemp = m_vP; //save
m_vP += m_vP - m_vOldP + m_vA*dt*dt/2.0f; //update
m_vOldP = vTemp; //remember
m_nLastMoveTime = t; //update time
Chapter 2 Introduction to Game Physics with Box2D 20
21. Optimization
Assume dt is constant. In fact, make it 1.
D3DXVECTOR2 m_vP; //position
D3DXVECTOR2 m_vOldP; //previous position
D3DXVECTOR2 m_vA; //acceleration
Even better, ignore the divide by 2. Ramp the acceleration
down to compensate if you need to.
D3DXVECTOR2 vTemp = m_vP; //save
m_vP += m_vP - m_vOldP + m_vA; //update
m_vOldP = vTemp; //remember
Chapter 2 Introduction to Game Physics with Box2D 21
23. Implementation
Store each object’s position, acceleration, and last
move time.
D3DXVECTOR2 m_vP, m_vOldP, m_vA; //as before
int m_nLastMoveTime; //time of last move
We then update position multiple times per frame.
int t = timeGetTime(); //current time in ms
int dt = t - m_nLastMoveTime; //frame time
Chapter 2 Introduction to Game Physics with Box2D 23
24. Implementation
dt is typically in the range of tens of millisecs.
D3DXVECTOR2 vTemp;
for(int i=0; i<dt; i++){
vTemp = m_vP; //save
m_vP += m_vP - m_vOldP + m_vA; //update
m_vOldP = vTemp; //remember
} //for
m_nLastMoveTime = t; //update time
Chapter 2 Introduction to Game Physics with Box2D 24
26. Satisfying Constraints
• We mentioned earlier that Verlet integration makes it
easy to enforce constraints on the particles.
• For example, let’s model a stick by applying Verlet
integration to two particles at the ends of the stick.
• The constraint is that the distance between the
particles must remain constant.
• We move the particles at the ends of the stick
independently, then try to fix their positions before
rendering if they are the wrong distance apart.
Chapter 2 Introduction to Game Physics with Box2D 26
27. fLen
A Sticky Situation m_vP1
m_vP2
Suppose its ends are at positions m_vP1 and
m_vP2, and it is supposed to have length LEN.
const float LEN = 42.0f;
D3DXVECTOR2 m_vP1, m_vP2;
First we get a vector vStick along the stick
and find its length fLen.
D3DXVECTOR2 vStick = m_vP1 - m_vP2;
float fLen = D3DXVec2Length(&vStick);
Chapter 2 Introduction to Game Physics with Box2D 27
28. fLen
A Sticky Situation m_vP1
m_vP2
LEN
Then we find the difference between the stick
now and what it should be.
vStick *= (fLen–LEN)/fLen;
We split the difference between the two ends.
m_vP1 += 0.5f * vStick;
m_vP2 -= 0.5f * vStick;
So far, so good.
Chapter 2 Introduction to Game Physics with Box2D 28
29. One Stick Summary Remember this
code. We’ll use
Declarations: it again 3 slides
from now
D3DXVECTOR2 vStick;
float fLen;
Code:
vStick = m_vP1 - m_vP2;
fLen = D3DXVec2Length(&vStick);
vStick *= (fLen–LEN)/fLen;
m_vP1 += 0.5f * vStick;
m_vP2 -= 0.5f * vStick;
Chapter 2 Introduction to Game Physics with Box2D 29
30. Two Sticks
But what if we’ve got 2 sticks joined at the ends?
m_vP3 m_vP3
m_vP1
m_vP2 m_vP1
m_vP2
Satisfying one constraint may violate the other.
m_vP3
m_vP1
m_vP2
Chapter 2 Introduction to Game Physics with Box2D 30
31. Declarations
Using the same declarations as before:
const float LEN = 42.0f
D3DXVECTOR2 m_vP1, m_vP2, m_vP3;
D3DXVECTOR2 vStick1, vStick2;
float fLen;
Chapter 2 Introduction to Game Physics with Box2D 31
32. We saw
Treat the Sticks Independently
this code 3
slides ago
vStick = m_vP1 - m_vP2;
fLen = D3DXVec2Length(&vStick);
vStick *= (fLen–LEN)/fLen;
m_vP1 += 0.5f * vStick; Remember
m_vP2 -= 0.5f * vStick; this code.
We’ll use it
vStick = m_vP2 - m_vP3; again 2 slides
fLen = D3DXVec2Length(&vStick); from now
Ditto
vStick *= (fLen–LEN)/fLen;
m_vP2 += 0.5f * vStick;
m_vP3 -= 0.5f * vStick;
Chapter 2 Introduction to Game Physics with Box2D 32
33. Details
• The code is not exactly as we drew it in the picture.
• When we move m_vP2 the second time, it’s not
starting from its original position.
• But it’s making progress towards where it needs to be.
m_vP2 m_vP2
m_vP2
Chapter 2 Introduction to Game Physics with Box2D 33
34. Relaxation
Repeat the process. It’s called relaxation.
const int ITERATIONS = 7;
for(int i=0; i<ITERATIONS; i++){
vStick = m_vP1 - m_vP2;
fLen = D3DXVec2Length(&vStick);
vStick *= (fLen–LEN)/fLen;
m_vP1 += 0.5f * vStick;
m_vP2 -= 0.5f * vStick; We saw
this code 2
vStick = m_vP2 - m_vP3;
slides ago.
fLen = D3DXVec2Length(&vStick);
vStick *= (fLen–LEN)/fLen;
m_vP2 += 0.5f * vStick;
m_vP3 -= 0.5f * vStick;
} //for
Chapter 2 Introduction to Game Physics with Box2D 34
35. Springs
To make springs instead of sticks, replace:
vStick *= (fLen–LEN)/fLen;
with the following, where m_fRestitution is a
coefficient of restitution between 0 and 1:
vStick *= m_fRestitution*(fLen–LEN)/fLen;
0 1
Chapter 2 Introduction to Game Physics with Box2D 35
36. Jacobi/Gauss/Seidel Iteration
• This is Jacobi or Gauss-Seidel iteration. Jacobi
• It is a general method for satisfying
multiple constraints that works quite
well.
• “Works quite well” means that if the
Gauss
conditions are right, it will converge.
• The number of ITERATIONS will
depend on the physical system being
modeled, and details such as the speeds
and the floating point precision.
Seidel
Chapter 2 Introduction to Game Physics with Box2D 36
Scary names, but we can handle it. We’re programmers! We’re not afraid of math, are we?
A little movie just to keep them interested. Your students may be tired of math already. This should help motivate them by showing them *why* we need the math… to do cool things!
Just when you thought you’d never actually need calculus in computer science classes.
Time is discrete. We only know where things are at discrete time slices. Riff on Heisenberg here if you wish. Yes, we can know both position and velocity.
Experience game programmers will be cool with this. Others may not be. Add salt to taste.
Image at right from Wikimedia Commons.
Easy.
Fictional units here. There’s a reason for this, of course as the instructor you’ve read my book already so you know why this is, right? I’m foreshadowing.
An allusion to Goldilocks in the next 2 slides wouldn’t be too out of place.
Don’t just wave your hands. Go through the first few lines of this table, emphasis on the last column.
If the real world were continuous, which it ain’timho.
Clearly the blue area is different.
Usually all of the math in this class comes from dead mathematicians a couple of centuries ago. This one is apparently still alive (fingers crossed). You might want to google him.He wrote the book at right, which is totally irrelevant for this class. See if anybody can translate the line at the bottom of the cover.
Yes, we will back up these claims by actually doing some of it later.
Slow and steady. Use the colors to orient yourself. Don’t forget that time is discrete. More on the next slide.
The first equation on this slide is the last equation from the previous slide. Keep slogging on.The last equation is the key, as we will see on the next slide.
The first equation on this slide is the last equation from the previous slide.Here’s why we like it.
For students who think in geometry better than algebra.
Now for some code. You might want to compare this with the code for Euler integration from Slide 8 or thereabouts.
Remember, we want this to be fast because we’re going to have scads of particles in our game.If anybody objects to making t=1 (trust me, there will probably be one in the audience), defer them to the next slide.
Done. Now on to the next section.
Gauss-Seidel relaxation in other words.
I’ve tried this using Euler integration before, and trust me, you don’t want to go there. It’s not pretty.
March through this.
It’s that first line of code, the (fLen-LEN)/fLen that makes it Gauss-Seidel. There are other functions of fLen and LEN that you can try (eg (fLen+LEN)/2), but almost all of them fail dramatically.If you don’t believe me, code it up and see.
Pause for breath, make sure the audience is still with you at this point.
Show this last statement by waving your hands and drawing pictures on the whiteboard. I’m not going to provide you with an animation for *everything*! Life’s too short.
That’s me relaxing on the beach in the Caribbean. Naturally I was only relaxing on the outside. On the inside I was thinking about code.
The closer to zero you get, the weaker the spring gets. The closer to one you get the more stick-like it gets.
Images on the right from Wikimedia Commons. More dead mathematicians. We’re done. Time to end the class.