logo SERENITY
Game Systems Foundation
Search Results for

    Show / Hide Table of Contents

    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.

    Inheritance
    object
    GaitCycleSolver
    Inherited Members
    object.ToString()
    object.Equals(object)
    object.Equals(object, object)
    object.ReferenceEquals(object, object)
    object.GetHashCode()
    object.GetType()
    object.MemberwiseClone()
    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 sin/cos is used, so values outside [0, 1] are still well-defined (periodic), but callers are expected to pass an already-wrapped [0, 1) value (see RailShooter.Enemy.Domain.Services's EnemyGaitPhaseSolver).

    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 phase01.

    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 dirForward and (when moving backward) by backwardStrideAmplitudeScale.

    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 dirForward.

    double upperArmAmplitudeDegrees

    Peak counter-swing amplitude (degrees) for the same-side upper arm (opposite phase to the same-side leg), scaled by dirForward.

    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 dirLateral and the leading/trailing asymmetry from lateralStepAsymmetry.

    double backwardStrideAmplitudeScale

    Thigh-swing amplitude multiplier at full backward travel (dirForward == -1), blended continuously from 1.0 at dirForward >= 0 down to this value at dirForward == -1. A real backward walk takes shorter, more cautious strides than a forward walk; pass 1.0 to disable (no shortening).

    double lateralStepAsymmetry

    Leading/trailing abduction asymmetry factor for a strafe: the leg on the side dirLateral points toward (the leading, stepping-out leg) gets amplitude scaled by (1 + lateralStepAsymmetry * dirLateral); the trailing leg gets (1 - lateralStepAsymmetry * dirLateral). Pass 0.0 to disable (symmetric left/right abduction, the pre-asymmetry behavior).

    Returns
    Type Description
    GaitPose

    The resolved GaitPose for phase01 and the given travel direction.

    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 dirForward == 1.

    double backwardLeanDegrees

    Peak backward lean magnitude (degrees, positive) at dirForward == -1 — typically larger than forwardLeanDegrees.

    double lateralLeanDegrees

    Peak lateral roll (degrees) at dirLateral == 1.

    double headYawDegrees

    Peak head yaw (degrees) toward the travel direction at dirLateral == 1.

    Returns
    Type Description
    DirectionalLeanPose

    The resolved DirectionalLeanPose.

    In this article
    © 2026 Serenity. All Rights Reserved