approximate measurements of rope in the Source engine are available here
this will look at non-solid ropes that aren't affected by wind
a JS implementation is available
Ropes in the Source engine span from a move_rope
to a keyframe_rope
(or from a keyframe_rope
to a keyframe_rope
).
In both cases two values are relevant for the rope simulation: slack and subdivision.
Slack indicates how low the rope hangs. It is simply a scalar value (usually in the range of a few hundred) that is added to the length of the rope when it is initialized [1].
This means that, for a 10-segment rope, each segment has an additional length of slack / 10
. When simulating, this will lead to a rope that hangs lower.
Subdivision indicates how smooth the rope is. It does not affect simulation directly, but is applied before rendering through applying a catmull rom spline. This smooths out the otherwise coarse 10-segment ropes.
The ropes are generated of 10 different nodes including start/end, connected by 9 springs. Each spring is given a length of (distFromStartToEnd + slack + fudge) / numSprings
.
Once the rope is generated it is simulated for 3 seconds worth of timesteps. This allows it to reach a resting state before it is displayed to the user.
Ropes are simulated using the simple physics engine. This simply applies the formula pos + vel * dampening + accel * (timestep * timestep * 0.5)
to each node, with a dampening factor of 0.98. The only forces that affect a non-solid rope that isn't affected by wind is gravity.
After this simple physical simulation is ran, constraints are applied. This loops 3 times, and each time it does the following:
- Run through all the springs and calculate
vTo
, a vector going fromNode2
toNode1
. - Check if the length of
vTo
is longer than the length of the spring. - If it is, multiply
vTo
by a factor of1 - (spring length / vTo length)
- Move
Node1
by-0.5 * vTo
- Move
Node2
by0.5 * vTo
- Move
This will keep the nodes from straying further from eachother than the spring length. If they are further than allowed, 1 - (expected / actual)
becomes a number in the range [0,1]
, being closer to 0 the closer they are to the expected length. This means that they are corrected to their expected length every time they are seen as too long.
After the nodes are simulated, the rope is smoothed based on the number of subdivisions the mapper has chosen. This calculates the Catmull-Rom spline with points prevNode
, curNode
, nextNode
and nextNextNode
. The point (t
) along the spline is set as (iSubdiv + 1) / (numSubdivs + 1)
, meaning that for a 2-subdiv the first point is at 1 / 3
, while the second one is 2 / 3
.