Game Development Reference
In-Depth Information
r 2 )= r 2 +
x
r 2 )= r 2 + x
2 r
1
2 r 2 ( x
f ( r 2 )+ f ( r 2 )( x
.
As expected, for x = r 2 ,weget x
r . Using the above approximation to
rewrite Equations (11.1)-(11.4), we end up with the following pseudocode:
// Pseudo code for satisfying a stick constraint
// using sqrt approximation
d=x2 x1; // OBS: vector operation; d, x1 and x2 are vectors
d =r r / (dotprod(d, d) + r r) 0.5;
x1 += d;
x2 =d;
Notice that if the distance is already correct (that is, if
||
x 2
x 1 ||
= r ), then we
get d =(0 , 0 , 0), and no change is going to happen.
Per constraint we now use zero square roots, one division only, and the squared
value r 2 can even be precalculated! The usage of time-consuming operations is
now down to N divisions per frame (and the correspondingmemory accesses)—it
can't be done much faster than that, and the result even looks quite nice. The con-
straints are not guaranteed to be satisfied after one iteration only, but because of
the Verlet integration scheme, the systemwill quickly converge to the correct state
over some frames. In fact, using only one iteration and approximating the square
root removes the stiffness that appears otherwise when the sticks are perfectly
stiff.
By placing support sticks between strategically chosen couples of vertices
sharing a neighbor, the cloth algorithm can be extended to simulate bending ob-
jects, such as plants. Again, in Hitman , only one pass through the relaxation loop
was enough (in fact, the low number gave the plants exactly the right amount of
bending behavior).
The code and the equations covered in this section assume that all particles
have identical mass. Of course, it is possible to model particles with different
masses; the equations only get a little more complex. To satisfy constraints while
respecting particle masses, use the following code:
// Pseudo code to satisfy a stick \ index { stick constraint } constraint with particle masses
d=x2 x1;
dlen = sqrt(dotprod(d,d));
f=(dlen r) / (dl (invmass1 + invmass2));
x1 += invmass1
f;
x2 = invmass2 d f;
d