Game Development Reference
In-Depth Information
Multiplying the vectors T , B , and N by 2 d does not change the direction in which
they point but does eliminate the divisions, yielding the following formulas.
(
)
(
)
T
B
N
=
2,0,
dzi j kzi j k
dzij k zij k
zi jk zi jk zij k zij k d
+
1,,
1,,
(
)
(
)
=
0, 2
,
,
+
1,
,
1,
(
)
(
)
(
)
(
)
=−
1,
,
−+
1,
,
,
,
−− +
1,
,
1,
, 2
(15.38)
Listing 15.1 demonstrates how a fluid surface simulation might be imple-
mented. It is important to realize that the time interval between evaluations of the
fluid displacement must be constant. The frame rate for most games varies con-
siderably, so some mechanism should be used to ensure that the position of the
surface is updated only after enough time has passed in situations when the frame
rate is high.
When an object interacts with the fluid surface (e.g., a rock is thrown into it),
it should cause a disturbance. The surface can be displaced by explicitly modify-
ing the current and previous positions of the vertices surrounding the point where
the interaction takes place. Displacing the vertex nearest to the point of impact
and, by a lesser amount, the eight nearest neighbors generally produces pleasing
results.
Listing 15.1. This code implements a two-buffer surface displacement algorithm. The constructor
of the Fluid class takes the size of the vertex array, the distance d between adjacent vertices, the
time interval t , the wave velocity c , and the viscosity μ . The renderBuffer member variable
indicates which buffer should be rendered for the current frame—it alternates between 0 and 1
during each call to the Fluid::Evaluate() function.
class Fluid
{
private :
long width;
long height;
Vector3D *buffer[2];
long renderBuffer;
Vector3D *normal;
Vector3D *tangent;
float k1, k2, k3;