// © 2024 Long Ly. All rights reserved. Any unauthorized use, reproduction, or distribution of this trademark is strictly prohibited and may result in legal action. #include "Data/OLSAnimationData.h" #include "Data/OLSEnumLibrary.h" void FOLSMovementDirectionThresholds::UpdateThresholds(const float fl, const float fr, const float bl, const float br, FOLSMovementDirectionThresholds& outMovementThresholds) { outMovementThresholds.FL = fl; outMovementThresholds.FR = fr; outMovementThresholds.BL = bl; outMovementThresholds.BR = br; } void FOLSFeetPositionData::DetermineIfRightFootIsFront() { const FVector rightFootLocal = RootTransform.InverseTransformPosition(RightFootLocation); const FVector leftFootLocal = RootTransform.InverseTransformPosition(LeftFootLocation); bIsRightFootFront = rightFootLocal.X > leftFootLocal.X; } bool FOLSFeetPositionData::IsRightFootFront() const { const FVector rightFootLocal = RootTransform.InverseTransformPosition(RightFootLocation); const FVector leftFootLocal = RootTransform.InverseTransformPosition(LeftFootLocation); return rightFootLocal.X > leftFootLocal.X; } UAnimSequence* FOLSTurnInPlaceAnimSet::GetTurnInPlaceAnimationByDirection(const float direction) const { if (FMath::Abs(direction) < 130.f) { return (direction > 0) ? TurnInPlace_90_R : TurnInPlace_90_L; } return (direction > 0) ? TurnInPlace_180_R : TurnInPlace_180_L; } bool FOLSIdleAnimSet::HasAnyIdleBreaks() const { return !IdleBreaks.IsEmpty(); } UAnimSequence* FOLSIdleAnimSet::GetIdleAnimation() const { return Idle; } UAnimSequence* FOLSIdleAnimSet::GetRandomIdleBreakAnimation() const { if (!HasAnyIdleBreaks()) { return nullptr; } const int32 idleBreaksNum = IdleBreaks.Num(); return IdleBreaks[FMath::RandRange(0, idleBreaksNum - 1)]; } UAnimSequence* FOLSIdleAndTurnInPlaceAnimSet::GetIdleExitAnimation() const { return IdleAnimSet.IdleExit; } UAnimSequence* FOLSIdleAndTurnInPlaceAnimSet::GetIdleAnimation() const { return IdleAnimSet.GetIdleAnimation(); } UAnimSequence* FOLSIdleAndTurnInPlaceAnimSet::GetRandomIdleBreakAnimation() const { return IdleAnimSet.GetRandomIdleBreakAnimation(); } UAnimSequence* FOLSIdleAndTurnInPlaceAnimSet::GetTurnInPlaceAnimation(const float direction) const { return TurnInPlaceAnimSet.GetTurnInPlaceAnimationByDirection(direction); } bool FOLSIdleAndTurnInPlaceAnimSet::CanPlayIdleBreakAnimation() const { return IdleAnimSet.HasAnyIdleBreaks(); } class UAnimSequence* FOLSMovementAnimSet_FeetPosition::GetForwardLeftOrRightFoot(const bool isRightFootFarFromTarget) const { return (isRightFootFarFromTarget ? RightFoot : LeftFoot); } class UAnimSequence* FOLSMovementAnimSet_ForwardFacing_StartCycle::GetForwardLeftOrRightFoot(const bool isRightFootFront) const { return Forward.GetForwardLeftOrRightFoot(isRightFootFront); } class UAnimSequence* FOLSMovementAnimSet_ForwardFacing_StartCycle::GetForward90LeftOrRightByAngle(const float angle) const { return (angle > 0.f) ? Forward90R : Forward90L; } UAnimSequence* FOLSMovementAnimSet_ForwardFacing_StartCycle::GetForward180LeftOrRightByAngle(const float angle) const { return (angle > 0.f) ? Forward180R : Forward180L; } class UAnimSequence* FOLSMovementAnimSet_ForwardFacing_StartCycle::GetMovementAnimationByAngle(const float angle, const bool isRightFootFront) const { TObjectPtr result = nullptr; const float absAngle = FMath::Abs(angle); if (angle >= -45.f && angle <= 45.f) { result = GetForwardLeftOrRightFoot(isRightFootFront); } else if (absAngle > 45.f && absAngle <= 135.f) { result = GetForward90LeftOrRightByAngle(angle); } else if (absAngle > 135.f && absAngle <= 180.f) { result = GetForward180LeftOrRightByAngle(angle); } return result; } class UAnimSequence* FOLSMovementAnimSet_ForwardFacing_Pivot::GetLeftOrRightByAngle(const float angle, const bool isRightFootFarFromTarget) const { return (angle > 0.f ? Pivot180R.GetForwardLeftOrRightFoot(isRightFootFarFromTarget) : Pivot180L.GetForwardLeftOrRightFoot(isRightFootFarFromTarget)); } UAnimSequence* FOLSMovementAnimSet_ForwardFacing_StopCycle::GetLeftOrRightAnim(const bool isRightFootPlanted) const { return Stop.GetForwardLeftOrRightFoot(isRightFootPlanted); } class UAnimSequence* FOLSMovementAnimSet_CameraFacing_Directional_Cycle::GetMovementAnimByCardinalDirection( const EOLSMovementDirection& direction) const { TObjectPtr result = nullptr; switch (direction) { case EOLSMovementDirection::EForward: result = Forward; break; case EOLSMovementDirection::EBackward: result = Backward; break; case EOLSMovementDirection::ELeftLeft: result = LeftLeft; break; case EOLSMovementDirection::ELeftRight: result = LeftRight; break; case EOLSMovementDirection::ERightRight: result = RightRight; break; case EOLSMovementDirection::ERightLeft: result = RightLeft; break; } return result; } void FOLSGaitAnimSet::GetPlayRateByLocomotionState(const EOLSLocomotionStatePlayRate& state, FVector2D& outPlayRate) const { switch (state) { case EOLSLocomotionStatePlayRate::EStart: outPlayRate = PlayRate_Start; break; case EOLSLocomotionStatePlayRate::ECycle: outPlayRate = PlayRate_Cycle; break; case EOLSLocomotionStatePlayRate::EPivot: outPlayRate = PlayRate_Pivot; break; } } void FOLSMovementAnimSet_CameraFacing_Directional::GetMovementAnimSetByCardinalDirection( const EOLSMovementDirection& direction, FOLSMovementAnimSet_FeetPosition& outAnimSet) const { switch (direction) { case EOLSMovementDirection::EForward: outAnimSet = Forward; break; case EOLSMovementDirection::EBackward: outAnimSet = Backward; break; case EOLSMovementDirection::ELeftLeft: outAnimSet = LeftLeft; break; case EOLSMovementDirection::ELeftRight: outAnimSet = LeftRight; break; case EOLSMovementDirection::ERightRight: outAnimSet = RightRight; break; case EOLSMovementDirection::ERightLeft: outAnimSet = RightLeft; break; } } UAnimSequence* FOLSMovementAnimSet_CameraFacing_Directional::GetMovementAnimByCardinalDirection( const EOLSMovementDirection& direction, const bool isRightFootFarFromTarget) const { FOLSMovementAnimSet_FeetPosition animSet; GetMovementAnimSetByCardinalDirection(direction, animSet); return animSet.GetForwardLeftOrRightFoot(isRightFootFarFromTarget); } UAnimSequence* FOLSStanceAnimSets::GetIdleAnimation() const { return IdleAndTurnInPlaceAnimSet.GetIdleAnimation(); } UAnimSequence* FOLSStanceAnimSets::GetIdleExitAnimation() const { return IdleAndTurnInPlaceAnimSet.GetIdleExitAnimation(); } UAnimSequence* FOLSStanceAnimSets::GetRandomIdleBreakAnimation() const { return IdleAndTurnInPlaceAnimSet.GetRandomIdleBreakAnimation(); } UAnimSequence* FOLSStanceAnimSets::GetTurnInPlaceAnimation(const float direction) const { return IdleAndTurnInPlaceAnimSet.GetTurnInPlaceAnimation(direction); } bool FOLSStanceAnimSets::CanPlayIdleBreakAnimation() const { return false; } const FOLSGaitAnimSets& FOLSStanceAnimSets::GetGaitAnimSetByGait(const EOLSGait& gait) const { return WalkAnimSets; } const FOLSGaitAnimSets& FOLSStanceAnimSets_Standing::GetGaitAnimSetByGait(const EOLSGait& gait) const { switch (gait) { case EOLSGait::EWalk: return WalkAnimSets; break; case EOLSGait::EJog: return JogAnimSets; case EOLSGait::ESprint: return SprintAnimSets; } return FOLSStanceAnimSets::GetGaitAnimSetByGait(gait); } FOLSGaitAnimSets FOLSGaitAnimSets::EmptyAnimSet = FOLSGaitAnimSets();