Game Development Reference

In-Depth Information

ApplyRopeImpulse(
float
P)

{

bodies[0].ApplyImpulse(d[0]
∗
P);

for
(
int
i=1; i
<
N; i++)

bodies[i].ApplyImpulse((d[i]
−
d[i
−
1])
∗
P);

bodies[N].ApplyImpulse(d[N
−
1]
∗−
P);

// same procedure is used for applying test impulse,

// except body impulses are accumulated in a special set of P,L

float
MeasureVelocityResponse()

{

ApplyTestImpulse(1.0f);

// compute v test and w test for each body as velocity changes

// due to test impulses

// compute v[i] = bodies[i].v test + (bodies[i].w test ˆ

// pt[i]
−
bodies[i].center)

float
dv = v[N]
∗
d[N]
−
v[0]
∗
d[0];

for
(
int
i=1; i
<
N; i++)

dv += v[i]
∗
(d[i
−
1]
−
d[i]);

return
dv;
//now 1/dv can be precomputed

}

The final push will be to add friction in the pull direction (see
Figure 8.5
)
.

The first thing to do is separate contact vertices with static and dynamic fric-

tion. It would make sense to assume that all contacts with tan(
α
)
<μ
(the friction

coefficient) are static and the rest are dynamic, applying friction impulse in the

direction opposite to the current slide velocity, in accordance with the Coulomb

law (in reality some of the latter might actually become static during the solv-

ing process, but not addressing that immediately in the same frame sounds like a

reasonable approximation).

Static friction contacts can be handled by simply splitting the rope constraint

into several parts so that each one has no static contacts in the middle (series of

consecutive static contacts with the same object can be merged).

For the dynamic sliding contacts, the velocity Equation (8.3) thankfully re-

mains the same. To find the impulses, we'll use the same idea that impulses

applied to each contact vertex sum up to zero. Assuming that P
i
and P
i
are the

(scalar) impulses that pull a vertex towards its left and right neighbors, respec-

tively, and P
i
is the normal impulse from the object, we can write the following:

(P
i

+P
i
)cos
α
=P
i
,

(8.4)

(P
i

+P
i
)sin
α
=
μ
P
i
.