public static void Lerp(ref PlayerPose result, PlayerPose lhs, PlayerPose rhs, float lerp)
 {
     result.LegUpperPitch  = Mathf.Lerp(lhs.LegUpperPitch, rhs.LegUpperPitch, lerp);
     result.LegUpperRoll   = Mathf.Lerp(lhs.LegUpperRoll, rhs.LegUpperRoll, lerp);
     result.LegUpperSpread = Mathf.Lerp(lhs.LegUpperSpread, rhs.LegUpperSpread, lerp);
     result.LegLowerPitch  = Mathf.Lerp(lhs.LegLowerPitch, rhs.LegLowerPitch, lerp);
     result.ArmUpperPitch  = Mathf.Lerp(lhs.ArmUpperPitch, rhs.ArmUpperPitch, lerp);
     result.ArmUpperRoll   = Mathf.Lerp(lhs.ArmUpperRoll, rhs.ArmUpperRoll, lerp);
     result.ArmClose       = Mathf.Lerp(lhs.ArmClose, rhs.ArmClose, lerp);
     result.ArmLowerPitch  = Mathf.Lerp(lhs.ArmLowerPitch, rhs.ArmLowerPitch, lerp);
     result.ShoulderPitch  = Mathf.Lerp(lhs.ShoulderPitch, rhs.ShoulderPitch, lerp);
     result.TorsoPitch     = Mathf.Lerp(lhs.TorsoPitch, rhs.TorsoPitch, lerp);
 }
        public static void ApplyPose(ref CharacterMuscleOutput o, PlayerPose p)
        {
            o.ShoulderLPitch += p.ShoulderPitch;
            o.ShoulderRPitch += p.ShoulderPitch;

            o.ArmLUpperPitch += p.ArmUpperPitch;
            o.ArmRUpperPitch += p.ArmUpperPitch;
            o.ArmLUpperRoll  -= p.ArmUpperRoll;
            o.ArmRUpperRoll  += p.ArmUpperRoll;
            o.ArmLLowerPitch += p.ArmLowerPitch;
            o.ArmRLowerPitch += p.ArmLowerPitch;
            o.ArmLClose      -= p.ArmClose;
            o.ArmRClose      += p.ArmClose;
            o.LegLLowerPitch += p.LegLowerPitch;
            o.LegRLowerPitch += p.LegLowerPitch;
            o.LegLUpperPitch += p.LegUpperPitch;
            o.LegRUpperPitch += p.LegUpperPitch;
            o.LegLUpperRoll  -= p.LegUpperRoll;
            o.LegRUpperRoll  += p.LegUpperRoll;
            o.LegLUpperClose += p.LegUpperSpread;
            o.LegRUpperClose -= p.LegUpperSpread;
            o.TorsoPitch     += p.TorsoPitch;
        }
 private void Awake()
 {
     _currentPose        = new PlayerPose();
     _wingsuitStabilizer = new WingsuitStabilizer(_wingsuitStabilizerConfig);
 }
        private void AnimateWingsuit(CharacterInput input, CharacterMuscleLimits limits, CharacterParts parts)
        {
            PlayerPose.Lerp(ref _currentPose, _defaultPose, _curledPose, input.Cannonball);

            float normalizedSpeed = Mathf.Clamp01(_target.RelativeVelocity.magnitude / _wingsuitStabilizerConfig.MaxSpeed);

            input.CloseLeftArm  += Mathf.Pow(normalizedSpeed, 1.5f) * 0.25f;
            input.CloseRightArm += Mathf.Pow(normalizedSpeed, 1.5f) * 0.25f;

            float pitchUp   = Mathf.Min(0f, input.Pitch);
            float pitchDown = Mathf.Min(0f, -input.Pitch);

            CharacterMuscleOutput o = new CharacterMuscleOutput();

            /* Transform user input into joint angle modifications. (still in unit values) */
            o.ShoulderLPitch = input.Pitch + input.Roll - input.CloseLeftArm;
            o.ShoulderRPitch = input.Pitch - input.Roll - input.CloseRightArm;
            o.ArmLUpperPitch = input.Roll * 0.3f + pitchDown * 0f - input.CloseLeftArm * 0.5f;
            o.ArmRUpperPitch = -input.Roll * 0.3f + pitchDown * 0f - input.CloseRightArm * 0.5f;
            o.ArmLUpperRoll  = -input.Pitch;
            o.ArmRUpperRoll  = input.Pitch;
            o.ArmLLowerPitch = -input.Pitch * 1f + -input.Roll * 0.5f + input.CloseLeftArm * 0.0f;
            o.ArmRLowerPitch = -input.Pitch * 1f + input.Roll * 0.5f + input.CloseRightArm * 0.0f;
            o.ArmLClose      = -input.CloseLeftArm * 1f + pitchDown * 1f + input.Roll * (input.Roll < 0f ? 1f : 0f);
            o.ArmRClose      = input.CloseRightArm * 1f - pitchDown * 1f + input.Roll * (input.Roll > 0f ? 1f : 0f);
            o.LegLUpperPitch = pitchUp * 1.0f + Mathf.Pow(pitchDown, 2f) * 0.5f + input.Yaw * 0.25f;
            o.LegRUpperPitch = pitchUp * 1.0f + Mathf.Pow(pitchDown, 2f) * 0.5f - input.Yaw * 0.25f;
            o.LegLUpperRoll  = input.Roll;
            o.LegRUpperRoll  = input.Roll;
            o.LegLLowerPitch = pitchUp * 1f + Mathf.Pow(pitchDown, 2f) + input.Yaw * 1f;
            o.LegRLowerPitch = pitchUp * 1f + Mathf.Pow(pitchDown, 2f) - input.Yaw * 1f;
            o.TorsoPitch     = pitchUp * 0.5f;
            o.TorsoRoll      = input.Roll * 1f + input.Yaw * 1f;
            o.TorsoYaw       = input.Yaw * 0.5f;

            CharacterMuscleOutput.Clamp(ref o);
            CharacterMuscleOutput.ScaleToLimits(ref o, limits);
            CharacterMuscleOutput.ApplyPose(ref o, _currentPose);

            /* Apply a specific stability effect to just the arms (Todo: move this elsewhere, make configurable) */

            float armUpperPitchHeadingStability = 10f * Mathf.InverseLerp(15f, -5f, _target.AngleOfAttack);

            o.ArmLUpperPitch += armUpperPitchHeadingStability;
            o.ArmRUpperPitch += armUpperPitchHeadingStability;

            float armLowerPitchHeadingStability = 15f * Mathf.InverseLerp(20f, -5f, _target.AngleOfAttack);

            o.ArmLLowerPitch += armLowerPitchHeadingStability;
            o.ArmRLowerPitch += armLowerPitchHeadingStability;

            /* Apply user-configured pitch attitude offset */

            o.TorsoPitch     += limits.PitchAttitudeTorsoMax * _userConfig.PitchAttitude;
            o.LegLUpperPitch += limits.PitchAttitudeLegsMax * _userConfig.PitchAttitude;
            o.LegRUpperPitch += limits.PitchAttitudeLegsMax * _userConfig.PitchAttitude;

            /* Send new targets to all the joints */

            CharacterMuscleOutput.Output(ref o, parts);
        }