11#include <util/ue-header-guard-begin.h>
12#include "AnimationRuntime.h"
13#include "ChaosWheeledVehicleMovementComponent.h"
14#include <util/ue-header-guard-end.h>
16static float RollWheel(
float SpinAngle,
float Travel,
float Radius,
float MaxTravel)
18 const bool bHasRadius = Radius > UE_KINDA_SMALL_NUMBER;
19 const bool bTeleported = FMath::Abs(Travel) > MaxTravel;
20 if (!bHasRadius || bTeleported)
24 return FMath::UnwindDegrees(SpinAngle - FMath::RadiansToDegrees(Travel / Radius));
29 Super::NativeUpdateAnimation(DeltaSeconds);
54 return GetWheeledVehicleComponent() !=
nullptr &&
55 !
Vehicle.IsSimulatedByChaos() &&
56 !
Vehicle.IsWheelAnimationOverridden();
61 const UChaosWheeledVehicleMovementComponent *Movement = GetWheeledVehicleComponent();
62 const FTransform MeshTransform = GetSkelMeshComponent()->GetComponentTransform();
63 const USkeletalMesh *SkeletalMesh = GetSkelMeshComponent()->GetSkeletalMeshAsset();
66 for (int32 i = 0; i <
Wheels.Num(); ++i)
69 if (SkeletalMesh !=
nullptr)
71 const FReferenceSkeleton &RefSkeleton = SkeletalMesh->GetRefSkeleton();
72 const int32 BoneIndex = RefSkeleton.FindBoneIndex(Movement->WheelSetups[i].BoneName);
73 if (BoneIndex != INDEX_NONE)
76 FAnimationRuntime::GetComponentSpaceTransformRefPose(RefSkeleton, BoneIndex).GetLocation();
85 const UChaosWheeledVehicleMovementComponent *Movement = GetWheeledVehicleComponent();
86 if (Movement ==
nullptr)
90 if (
Wheels.Num() != Movement->WheelSetups.Num())
95 const FTransform MeshTransform = GetSkelMeshComponent()->GetComponentTransform();
98 Wheel.LastLocation = MeshTransform.TransformPosition(Wheel.RestLocation);
104 if (
Wheels.Num() != GetWheeledVehicleComponent()->WheelSetups.Num())
108 const TArray<FWheelAnimationData> &WheelPoses =
GetWheelPoses();
109 for (int32 i = 0; i <
Wheels.Num(); ++i)
112 Wheels[i].SpinAngle = WheelPoses.IsValidIndex(i) ? WheelPoses[i].RotOffset.Pitch : 0.0f;
119 const FTransform MeshTransform = GetSkelMeshComponent()->GetComponentTransform();
120 const FVector Forward = MeshTransform.GetUnitAxis(EAxis::X);
123 for (int32 i = 0; i <
Wheels.Num() && i < WheelPoses.Num(); ++i)
126 const FVector Location = MeshTransform.TransformPosition(Wheel.
RestLocation);
127 const float Travel = FVector::DotProduct(Location - Wheel.
LastLocation, Forward);
130 WheelPoses[i].RotOffset.Pitch = Wheel.
SpinAngle;
136 const bool bOverridden =
Vehicle.IsWheelAnimationOverridden();
140 const TArray<FWheelAnimationData> &OverriddenPoses =
Vehicle.GetOverriddenWheelPoses();
141 for (int32 i = 0; i < WheelPoses.Num() && i < OverriddenPoses.Num(); ++i)
143 WheelPoses[i].RotOffset = OverriddenPoses[i].RotOffset;
144 WheelPoses[i].LocOffset = OverriddenPoses[i].LocOffset;
151 for (FWheelAnimationData &Pose : WheelPoses)
153 Pose.RotOffset.Yaw = 0.0f;
154 Pose.LocOffset = FVector::ZeroVector;
162 const TArray<FWheelAnimationData> &WheelPoses =
163 GetProxyOnGameThread<FVehicleAnimationInstanceProxy>().GetWheelAnimData();
164 return WheelPoses.IsValidIndex(WheelIndex) ? &WheelPoses[WheelIndex] :
nullptr;
170 return const_cast<TArray<FWheelAnimationData> &
>(
171 GetProxyOnGameThread<FVehicleAnimationInstanceProxy>().GetWheelAnimData());
static float RollWheel(float SpinAngle, float Travel, float Radius, float MaxTravel)
Base class for CARLA wheeled vehicles.
void UpdateWheelAnimationOverride(const ACarlaWheeledVehicle &Vehicle)
float MaxTravelSpeed
cm/s. A wheel moving faster than this was teleported, and is not turned.
bool bWasWheelAnimationOverridden
void RollWheels(const ACarlaWheeledVehicle &Vehicle, float DeltaSeconds)
virtual void NativeUpdateAnimation(float DeltaSeconds) override
void TrackWheelLocations()
World locations of the wheels, kept while not rolling.
bool ShouldRollWheels(const ACarlaWheeledVehicle &Vehicle) const
const FWheelAnimationData * GetWheelPose(int32 WheelIndex) const
The pose last written for a wheel, or nullptr if there is no such wheel.
TArray< FWheelAnimationData > & GetWheelPoses()
FVector RestLocation
Reference pose, component space.
FVector LastLocation
World space, previous update.