public static void ScaleToLimits(ref CharacterMuscleOutput o, CharacterMuscleLimits l) { // linear motion, meters o.ShoulderLPitch *= l.ShoulderPitch; o.ShoulderRPitch *= l.ShoulderPitch; // angular motion, degrees o.ArmLUpperPitch *= l.ArmUpperPitch; o.ArmRUpperPitch *= l.ArmUpperPitch; o.ArmLUpperRoll *= l.ArmUpperRoll; o.ArmRUpperRoll *= l.ArmUpperRoll; o.ArmLLowerPitch *= l.ArmLowerPitch; o.ArmRLowerPitch *= l.ArmLowerPitch; o.ArmLClose *= l.ArmClose; o.ArmRClose *= l.ArmClose; o.LegLUpperPitch *= l.LegUpperPitch; o.LegRUpperPitch *= l.LegUpperPitch; o.LegLUpperRoll *= l.LegUpperRoll; o.LegRUpperRoll *= l.LegUpperRoll; o.LegLUpperClose *= l.LegUpperClose; o.LegRUpperClose *= l.LegUpperClose; o.LegLLowerPitch *= l.LegLowerPitch; o.LegRLowerPitch *= l.LegLowerPitch; o.TorsoPitch *= l.TorsoPitch; o.TorsoRoll *= l.TorsoRoll; o.TorsoYaw *= l.TorsoYaw; }
private void AnimateParachute(ParachuteInput input, CharacterMuscleLimits limits, CharacterParts parts) { CharacterMuscleOutput o = new CharacterMuscleOutput(); Vector2 lineInput = Max(input.Brakes, input.FrontRisers, input.RearRisers); /* Todo: Lower body has to try and cancel out oscillations about harness pivot * I suspect that if we can get a rough version of this going it'll be enough */ o.ArmLClose = -lineInput.x * 0.6f; o.ArmRClose = lineInput.y * 0.6f; o.LegLUpperPitch = Mathf.Abs(input.WeightShift.y) * 0.66f; o.LegRUpperPitch = Mathf.Abs(input.WeightShift.y) * 0.66f; o.LegLLowerPitch = input.WeightShift.y; o.LegRLowerPitch = input.WeightShift.y; o.LegLUpperClose -= input.WeightShift.x; o.LegRUpperClose -= input.WeightShift.x; o.TorsoPitch = -input.WeightShift.y; o.TorsoRoll = input.WeightShift.x * 0.66f; CharacterMuscleOutput.Clamp(ref o); CharacterMuscleOutput.ScaleToLimits(ref o, limits); CharacterMuscleOutput.ApplyPose(ref o, _parachutePose); CharacterMuscleOutput.Output(ref o, parts); }
public static void Output(ref CharacterMuscleOutput o, CharacterParts p) { p.LegLUpper.TargetRotation = Quaternion.Euler(o.LegLUpperPitch, o.LegLUpperRoll, o.LegLUpperClose); p.LegRUpper.TargetRotation = Quaternion.Euler(o.LegRUpperPitch, o.LegRUpperRoll, o.LegRUpperClose); p.LegLLower.TargetRotation = Quaternion.Euler(o.LegLLowerPitch, 0f, 0f); p.LegRLower.TargetRotation = Quaternion.Euler(o.LegRLowerPitch, 0f, 0f); p.ArmLUpper.TargetRotation = Quaternion.Euler(o.ArmLUpperPitch, o.ArmLUpperRoll, o.ArmLClose); p.ArmRUpper.TargetRotation = Quaternion.Euler(o.ArmRUpperPitch, o.ArmRUpperRoll, o.ArmRClose); p.ArmLLower.TargetRotation = Quaternion.Euler(o.ArmLLowerPitch, 0f, 0f); p.ArmRLower.TargetRotation = Quaternion.Euler(o.ArmRLowerPitch, 0f, 0f); p.Torso.TargetRotation = Quaternion.Euler(o.TorsoPitch, o.TorsoRoll, o.TorsoYaw); p.ArmLUpper.TargetPosition = new Vector3(0f, 0f, o.ShoulderLPitch); p.ArmRUpper.TargetPosition = new Vector3(0f, 0f, o.ShoulderRPitch); }
public static void Clamp(ref CharacterMuscleOutput o) { o.ShoulderLPitch = Mathf.Clamp(o.ShoulderLPitch, -1f, 1f); o.ShoulderRPitch = Mathf.Clamp(o.ShoulderRPitch, -1f, 1f); o.ArmLUpperPitch = Mathf.Clamp(o.ArmLUpperPitch, -1f, 1f); o.ArmRUpperPitch = Mathf.Clamp(o.ArmRUpperPitch, -1f, 1f); o.ArmLUpperRoll = Mathf.Clamp(o.ArmLUpperRoll, -1f, 1f); o.ArmRUpperRoll = Mathf.Clamp(o.ArmRUpperRoll, -1f, 1f); o.ArmLClose = Mathf.Clamp(o.ArmLClose, -1f, 1f); o.ArmRClose = Mathf.Clamp(o.ArmRClose, -1f, 1f); o.LegLUpperPitch = Mathf.Clamp(o.LegLUpperPitch, -1f, 1f); o.LegRUpperPitch = Mathf.Clamp(o.LegRUpperPitch, -1f, 1f); o.LegLUpperRoll = Mathf.Clamp(o.LegLUpperRoll, -1f, 1f); o.LegRUpperRoll = Mathf.Clamp(o.LegRUpperRoll, -1f, 1f); o.LegLUpperClose = Mathf.Clamp(o.LegLUpperClose, -1f, 1f); o.LegRUpperClose = Mathf.Clamp(o.LegRUpperClose, -1f, 1f); o.TorsoPitch = Mathf.Clamp(o.TorsoPitch, -1f, 1f); o.TorsoRoll = Mathf.Clamp(o.TorsoRoll, -1f, 1f); o.TorsoYaw = Mathf.Clamp(o.TorsoYaw, -1f, 1f); }
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 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); }