Class GaitCycleSolver
Pure walk-gait math: maps a normalized, wrapping cycle phase (0..1) to per-bone rotation offsets (degrees) and a hip vertical bob (meters). Uses only Math — no engine references — so the bone-axis table is unit-testable without a scene or engine.
Inherited Members
Namespace: Serenity.ProceduralAnimator.Domain.Services
Assembly: Serenity.ProceduralAnimator.Domain.dll
Syntax
public static class GaitCycleSolver
Remarks
One full phase cycle (0 -> 1) covers two footfalls (left contact, then right contact),
matching the two ~0.65m strides EnemyGaitPhaseSolver's cycle length represents.
Bone axis convention (X = pitch/flexion) is inferred from the rig and MUST be verified
against the live rig before tuning amplitudes — see the plan's bone-axis probe step. All
rotation outputs assume that convention; if the probe finds a different axis mapping, the
consuming layer (not this solver) is the place to remap which output degrees feed which
Euler axis.
Methods
Solve(double, double, double, double, double, double, double)
Resolves the full per-bone gait pose for a single phase sample, walking purely forward
(equivalent to Solve(double,double,double,double,double,double,double,double,double,double)
with dirForward = 1, dirLateral = 0, lateralAmplitudeDegrees = 0).
Kept for callers that only ever drive a forward walk cycle.
Declaration
public static GaitPose Solve(double phase01, double upperLegAmplitudeDegrees, double lowerLegAmplitudeDegrees, double footToeAmplitudeDegrees, double upperArmAmplitudeDegrees, double hipsTwistAmplitudeDegrees, double hipsBobMeters)
Parameters
| Type | Name | Description |
|---|---|---|
| double | phase01 | Normalized cycle phase. Only the fractional/periodic behavior of |
| double | upperLegAmplitudeDegrees | Peak thigh swing amplitude (degrees) about the same-side axis, antiphase left/right. |
| double | lowerLegAmplitudeDegrees | Peak knee flex amplitude (degrees). The output is flex-only (never positive) — no hyperextension. |
| double | footToeAmplitudeDegrees | Peak toe-off amplitude (degrees) added on top of the foot's thigh-follow term. |
| double | upperArmAmplitudeDegrees | Peak counter-swing amplitude (degrees) for the same-side upper arm (opposite phase to the same-side leg). |
| double | hipsTwistAmplitudeDegrees | Peak hip twist amplitude (degrees) about the vertical axis. |
| double | hipsBobMeters | Peak downward hip dip (meters), one dip per footfall (twice per full cycle). |
Returns
| Type | Description |
|---|---|
| GaitPose | The resolved GaitPose for |
Solve(double, double, double, double, double, double, double, double, double, double, double, double)
Resolves the full per-bone gait pose for a single phase sample, directional: the
sagittal (forward/back) swing terms scale by dirForward (signed — a
negative value naturally reverses the visual swing, producing a backward-walk look) and
a new lateral (sideways abduction/adduction) term on the upper legs scales by
dirLateral. Knee flex and the hip bob/twist scale by the OVERALL
travel-direction magnitude (not dirForward alone) so they still read
correctly during a pure strafe — see Serenity.ProceduralAnimator.Domain.Services.GaitCycleSolver.ResolveKneeAmplitudeScale(System.Double) and the
magnitude-scaled hip terms below.
Declaration
public static GaitPose Solve(double phase01, double dirForward, double dirLateral, double upperLegAmplitudeDegrees, double lowerLegAmplitudeDegrees, double footToeAmplitudeDegrees, double upperArmAmplitudeDegrees, double hipsTwistAmplitudeDegrees, double hipsBobMeters, double lateralAmplitudeDegrees, double backwardStrideAmplitudeScale, double lateralStepAsymmetry)
Parameters
| Type | Name | Description |
|---|---|---|
| double | phase01 | Normalized cycle phase — see the single-direction Solve(double, double, double, double, double, double, double) overload's remarks. |
| double | dirForward | Signed forward/backward travel-direction component, expected in roughly [-1, 1] (+1 = pure forward, -1 = pure backward, 0 = no sagittal component, e.g. pure strafe). |
| double | dirLateral | Signed lateral travel-direction component, expected in roughly [-1, 1] (+1 = pure strafe to the character's right, -1 = pure strafe left, 0 = no lateral component). |
| double | upperLegAmplitudeDegrees | Peak thigh swing amplitude (degrees) about the same-side sagittal axis, antiphase left/right, scaled by |
| double | lowerLegAmplitudeDegrees | Peak knee flex amplitude (degrees) before the direction-magnitude scale is applied. The output is flex-only (never positive) — no hyperextension, for any direction input. |
| double | footToeAmplitudeDegrees | Peak toe-off amplitude (degrees) added on top of the foot's thigh-follow term, scaled by |
| double | upperArmAmplitudeDegrees | Peak counter-swing amplitude (degrees) for the same-side upper arm (opposite phase to the same-side leg), scaled by |
| double | hipsTwistAmplitudeDegrees | Peak hip twist amplitude (degrees) about the vertical axis, scaled by the travel-direction magnitude. |
| double | hipsBobMeters | Peak downward hip dip (meters), one dip per footfall (twice per full cycle), scaled by the travel-direction magnitude. |
| double | lateralAmplitudeDegrees | Peak upper-leg abduction/adduction amplitude (degrees), antiphase left/right, scaled by |
| double | backwardStrideAmplitudeScale | Thigh-swing amplitude multiplier at full backward travel ( |
| double | lateralStepAsymmetry | Leading/trailing abduction asymmetry factor for a strafe: the leg on the side |
Returns
| Type | Description |
|---|---|
| GaitPose | The resolved GaitPose for |
Remarks
A sign flip alone (negating both antiphase legs) is perceptually invisible for a walk
cycle: -Asin(theta) == Asin(theta+PI), so negating both swings is mathematically
identical to swapping which leg is which and shifting the whole cycle half a period —
the SAME walk, just relabeled. backwardStrideAmplitudeScale and the
knee's phase-offset reversal below are the two real kinematic differences between a
forward and a backward walk (shorter stride, knee leads/lags the thigh on the opposite
side of the swing) that make the direction actually READ instead of just mirroring.
SolveLean(double, double, double, double, double, double)
Resolves a constant (non-oscillating) postural lean/look offset from the current travel
direction — NOT part of the periodic stride cycle, so it takes no phase input. Forward
travel leans the torso slightly forward; backward travel leans it back, more pronounced
(people lean back when retreating to keep their balance/guard up); lateral travel rolls
the torso into the step; and the head yaws slightly toward the lateral travel direction
(people look where they step). All three outputs are abstract sign conventions —
PitchDegrees positive = lean forward, RollDegrees/HeadYawDegrees
positive = toward dirLateral's positive side — the consuming layer is
responsible for mapping these onto each bone's own measured local axis and sign (see
the axis-convention notes on the layer that applies this).
Declaration
public static DirectionalLeanPose SolveLean(double dirForward, double dirLateral, double forwardLeanDegrees, double backwardLeanDegrees, double lateralLeanDegrees, double headYawDegrees)
Parameters
| Type | Name | Description |
|---|---|---|
| double | dirForward | Signed forward/backward travel-direction component, expected in roughly [-1, 1]. |
| double | dirLateral | Signed lateral travel-direction component, expected in roughly [-1, 1]. |
| double | forwardLeanDegrees | Peak forward lean (degrees) at |
| double | backwardLeanDegrees | Peak backward lean magnitude (degrees, positive) at |
| double | lateralLeanDegrees | Peak lateral roll (degrees) at |
| double | headYawDegrees | Peak head yaw (degrees) toward the travel direction at |
Returns
| Type | Description |
|---|---|
| DirectionalLeanPose | The resolved DirectionalLeanPose. |