3#include "Net/UnrealNetwork.h" 
    4#include "MotionControllerComponent.h" 
    7#include "XRMotionControllerBase.h"  
   11    : Super(ObjectInitializer)
 
   13    PrimaryComponentTick.bCanEverTick = 
true;
 
   14    PrimaryComponentTick.bStartWithTickEnabled = 
true;
 
   21    SetIsReplicatedByDefault(
true);
 
 
   25void UOpenXRHandPoseComponent::GetLifetimeReplicatedProps(TArray< class FLifetimeProperty > & OutLifetimeProps)
 const 
   27    Super::GetLifetimeReplicatedProps(OutLifetimeProps);
 
   34void UOpenXRHandPoseComponent::Server_SendSkeletalTransforms_Implementation(
const FBPSkeletalRepContainer& SkeletalInfo)
 
   62bool UOpenXRHandPoseComponent::Server_SendSkeletalTransforms_Validate(
const FBPSkeletalRepContainer& SkeletalInfo)
 
   69    Super::PreUpdate(InAnimInstance, DeltaSeconds);
 
   73        if (OwningInstance->OwningPoseComp)
 
   86                for (
int i = 0; i < OwningInstance->OwningPoseComp->HandSkeletalActions.Num(); ++i)
 
 
  150        bool bGetCompressedTransforms = 
false;
 
  157                bGetCompressedTransforms = 
true;
 
  165                if (bGetCompressedTransforms)
 
  167                    if (GetNetMode() == NM_Client)
 
  169                        if (actionInfo.bHasValidData)
 
  178                        if (actionInfo.bHasValidData)
 
  196    Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
 
 
  234        FVector WristLoc = FVector::ZeroVector;
 
  245        for (
int i = 0; i < 5; ++i)
 
  257        NewGesture.
Name = RecordingName;
 
 
  281    FVector WristLoc = FVector::ZeroVector;
 
  293    TArray<FVector> CurrentTips;
 
  294    CurrentTips.AddUninitialized(5);
 
  295    for (
int i = 0; i < 5; ++i)
 
  299            CurrentTips[i] = SkeletalAction.SkeletalTransforms[FingerMap[i]].GetLocation().MirrorByVector(FVector::RightVector) - WristLoc;
 
  303            CurrentTips[i] = SkeletalAction.SkeletalTransforms[FingerMap[i]].GetLocation() - WristLoc;
 
  310        if (Gesture.FingerValues.Num() < 5 || SkeletalAction.SkeletalTransforms.Num() < EHandKeypointCount)
 
  313        bool bDetectedPose = 
true;
 
  314        for (
int i = 0; i < 5; ++i)
 
  316            FVector GestureV = Gesture.FingerValues[i].Value;
 
  317            FVector CurrentV = CurrentTips[i];
 
  318            FVector Difference = GestureV - CurrentV;
 
  320            if (!Gesture.FingerValues[i].Value.Equals(CurrentTips[i], Gesture.FingerValues[i].Threshold))
 
  322                bDetectedPose = 
false;
 
  329            GestureOut = Gesture;
 
 
  342    FTransform BoneTransform = FTransform::Identity;
 
  353    FVector WristLoc = FVector::ZeroVector;
 
  365    TArray<FVector> CurrentTips;
 
  366    CurrentTips.AddUninitialized(5);
 
  367    for (
int i = 0; i < 5; ++i)
 
  371            CurrentTips[i] = SkeletalAction.
SkeletalTransforms[FingerMap[i]].GetLocation().MirrorByVector(FVector::RightVector) - WristLoc;
 
  375            CurrentTips[i] = SkeletalAction.
SkeletalTransforms[FingerMap[i]].GetLocation() - WristLoc;
 
  379    for (
auto GestureIterator = 
GesturesDB->
Gestures.CreateConstIterator(); GestureIterator; ++GestureIterator)
 
  387        bool bDetectedPose = 
true;
 
  388        for (
int i = 0; i < 5; ++i)
 
  395                bDetectedPose = 
false;
 
 
  438    UpdateRate = (1.0f / NetUpdateRate);
 
  447        bReplicatedOnce = 
true;
 
 
  458        UpdateCount += DeltaTime;
 
  459        float LerpVal = FMath::Clamp(UpdateCount / UpdateRate, 0.0f, 1.0f);
 
  470            if ((NewTransforms.Num() < (EHandKeypointCount - BoneCountAdjustment)) || (NewTransforms.Num() != ActionInfo.
SkeletalTransforms.Num() || NewTransforms.Num() != ActionInfo.
OldSkeletalTransforms.Num()))
 
 
  532    TargetHand = 
Other.TargetHand;
 
  534    if (!
Other.bHasValidData)
 
  537    bAllowDeformingMesh = 
Other.bAllowDeformingMesh;
 
  538    bEnableUE4HandRepSavings = 
Other.bEnableUE4HandRepSavings;
 
  543    if (
Other.SkeletalTransforms.Num() < EHandKeypointCount)
 
  545        SkeletalTransforms.Empty();
 
  549    int32 BoneCountAdjustment = 5 + (bEnableUE4HandRepSavings ? 4 : 0);
 
  551    if (SkeletalTransforms.Num() != EHandKeypointCount - BoneCountAdjustment)
 
  553        SkeletalTransforms.Reset(EHandKeypointCount - BoneCountAdjustment); 
 
  554        SkeletalTransforms.AddUninitialized(EHandKeypointCount - BoneCountAdjustment);
 
  565    if (!bEnableUE4HandRepSavings)
 
  573    if (!bEnableUE4HandRepSavings)
 
  581    if (!bEnableUE4HandRepSavings)
 
  589    if (!bEnableUE4HandRepSavings)
 
 
  603        Other.SkeletalTransforms.Empty();
 
  604        Other.bHasValidData = 
false;
 
  614    if (
Other.SkeletalTransforms.Num() != EHandKeypointCount)
 
  615        Other.SkeletalTransforms.Reset(EHandKeypointCount);
 
  617        Other.SkeletalTransforms.AddUninitialized(EHandKeypointCount);
 
  678    Other.bHasValidData = 
true;
 
 
  685    Ar.SerializeBits(&TargetHand, 1);
 
  686    Ar.SerializeBits(&bAllowDeformingMesh, 1);
 
  687    Ar.SerializeBits(&bEnableUE4HandRepSavings, 1);
 
  689    int32 BoneCountAdjustment = 5 + (bEnableUE4HandRepSavings ? 4 : 0);
 
  690    uint8 TransformCount = EHandKeypointCount - BoneCountAdjustment;
 
  696        SkeletalTransforms.Reset(TransformCount);
 
  699    FVector Position = FVector::ZeroVector;
 
  700    FRotator Rot = FRotator::ZeroRotator;
 
  702    for (
int i = 0; i < TransformCount; i++)
 
  706            if (bAllowDeformingMesh)
 
  707                Position = SkeletalTransforms[i].GetLocation();
 
  709            Rot = SkeletalTransforms[i].Rotator();
 
  712        if (bAllowDeformingMesh)
 
  713            bOutSuccess &= SerializePackedVector<10, 11>(Position, Ar);
 
  715        Rot.SerializeCompressed(Ar); 
 
  719            if (bAllowDeformingMesh)
 
  720                SkeletalTransforms.Add(FTransform(Rot, Position));
 
  722                SkeletalTransforms.Add(FTransform(Rot));
 
 
  731    Super::NativeBeginPlay();
 
  733    AActor* Owner = GetOwningComponent()->GetOwner();
 
  738        HandPoseComp = Owner->GetComponentByClass(UOpenXRHandPoseComponent::StaticClass());
 
  743            if (Owner->GetOwner())
 
  745                HandPoseComp = Owner->GetOwner()->GetComponentByClass(UOpenXRHandPoseComponent::StaticClass());
 
  757        OwningPoseComp = HandComp;
 
 
  795    USkeleton* AssetSkeleton = this->CurrentSkeleton;
 
  799        FBoneContainer& RequiredBones = this->GetRequiredBones();
 
  803            BonePair.ReferenceToConstruct.BoneName = BonePair.BoneToTarget;
 
  806            BonePair.ReferenceToConstruct.Initialize(AssetSkeleton);
 
  807            BonePair.ReferenceToConstruct.CachedCompactPoseIndex = BonePair.ReferenceToConstruct.GetCompactPoseIndex(RequiredBones);
 
  809            if ((BonePair.ReferenceToConstruct.CachedCompactPoseIndex != INDEX_NONE))
 
  812                BonePair.ParentReference = RequiredBones.GetParentBoneIndex(BonePair.ReferenceToConstruct.CachedCompactPoseIndex);
 
  816        if (
UObject* OwningAsset = RequiredBones.GetAsset())
 
  818            SkeletalMappingData.LastInitializedName = OwningAsset->GetFName();
 
  821        SkeletalMappingData.bInitialized = 
true;
 
  825    SkeletalMappingData.bInitialized = 
false;
 
 
EVRSkeletalHandIndex
UENUM(BlueprintType)
 
EXRHandJointType
UENUM(BlueprintType)
 
@ OXR_HAND_JOINT_LITTLE_TIP_EXT
 
@ OXR_HAND_JOINT_MIDDLE_PROXIMAL_EXT
 
@ OXR_HAND_JOINT_RING_DISTAL_EXT
 
@ OXR_HAND_JOINT_RING_METACARPAL_EXT
 
@ OXR_HAND_JOINT_MIDDLE_METACARPAL_EXT
 
@ OXR_HAND_JOINT_RING_PROXIMAL_EXT
 
@ OXR_HAND_JOINT_RING_INTERMEDIATE_EXT
 
@ OXR_HAND_JOINT_INDEX_TIP_EXT
 
@ OXR_HAND_JOINT_PALM_EXT
 
@ OXR_HAND_JOINT_LITTLE_METACARPAL_EXT
 
@ OXR_HAND_JOINT_MIDDLE_INTERMEDIATE_EXT
 
@ OXR_HAND_JOINT_INDEX_PROXIMAL_EXT
 
@ OXR_HAND_JOINT_WRIST_EXT
 
@ OXR_HAND_JOINT_INDEX_INTERMEDIATE_EXT
 
@ OXR_HAND_JOINT_MIDDLE_TIP_EXT
 
@ OXR_HAND_JOINT_THUMB_TIP_EXT
 
@ OXR_HAND_JOINT_LITTLE_PROXIMAL_EXT
 
@ OXR_HAND_JOINT_THUMB_METACARPAL_EXT
 
@ OXR_HAND_JOINT_MIDDLE_DISTAL_EXT
 
@ OXR_HAND_JOINT_LITTLE_DISTAL_EXT
 
@ OXR_HAND_JOINT_INDEX_DISTAL_EXT
 
@ OXR_HAND_JOINT_RING_TIP_EXT
 
@ OXR_HAND_JOINT_THUMB_DISTAL_EXT
 
@ OXR_HAND_JOINT_THUMB_PROXIMAL_EXT
 
@ OXR_HAND_JOINT_INDEX_METACARPAL_EXT
 
@ OXR_HAND_JOINT_LITTLE_INTERMEDIATE_EXT
 
UCLASS(transient, Blueprintable, hideCategories = AnimInstance, BlueprintType)
 
virtual void NativeBeginPlay() override
 
void InitializeCustomBoneMapping(UPARAM(ref) FBPOpenXRSkeletalMappingData &SkeletalMappingData)
UFUNCTION(BlueprintCallable, Category = "BoneMappings")
 
static bool GetOpenXRHandPose(FBPOpenXRActionSkeletalData &HandPoseContainer, UOpenXRHandPoseComponent *HandPoseComponent, bool bGetMockUpPose=false)
UFUNCTION(BlueprintCallable, Category = "VRExpansionFunctions|OpenXR", meta = (bIgnoreSelf = "true"))
 
TArray< FOpenXRGesture > Gestures
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VRGestures")
 
UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent))
 
FTransformLerpManager LeftHandRepManager
 
bool bSmoothReplicatedSkeletalData
UPROPERTY(EditAnywhere, Category = SkeletalData)
 
TArray< FBPOpenXRActionSkeletalData > HandSkeletalActions
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SkeletalData|Actions")
 
FBPSkeletalRepContainer RightHandRep
UPROPERTY(Replicated, Transient, ReplicatedUsing = OnRep_SkeletalTransformRight)
 
bool bDetectGestures
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VRGestures")
 
void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override
 
bool bGetMockUpPoseForDebugging
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SkeletalData|Actions")
 
bool SaveCurrentPose(FName RecordingName, EVRSkeletalHandIndex HandToSave=EVRSkeletalHandIndex::EActionHandIndex_Right)
UFUNCTION(BlueprintCallable, Category = "VRGestures")
 
bool bReplicateSkeletalData
UPROPERTY(EditAnywhere, Category = SkeletalData)
 
FBPSkeletalRepContainer LeftHandRep
UPROPERTY(Replicated, Transient, ReplicatedUsing = OnRep_SkeletalTransformLeft)
 
UOpenXRGestureDatabase * GesturesDB
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VRGestures")
 
UOpenXRHandPoseComponent(const FObjectInitializer &ObjectInitializer)
 
FOpenXRGestureEnded OnGestureEnded
UPROPERTY(BlueprintAssignable, Category = "VRGestures")
 
float ReplicationRateForSkeletalAnimations
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = SkeletalData)
 
float SkeletalNetUpdateCount
 
bool K2_DetectCurrentPose(UPARAM(ref) FBPOpenXRActionSkeletalData &SkeletalAction, FOpenXRGesture &GestureOut)
UFUNCTION(BlueprintCallable, Category = "VRGestures", meta = (DisplayName = "DetectCurrentPose"))
 
virtual void BeginPlay() override
 
FOpenXRGestureDetected OnNewGestureDetected
UPROPERTY(BlueprintAssignable, Category = "VRGestures")
 
bool DetectCurrentPose(FBPOpenXRActionSkeletalData &SkeletalAction)
 
bool IsLocallyControlled() const
 
FTransformLerpManager RightHandRepManager
 
void Server_SendSkeletalTransforms(const FBPSkeletalRepContainer &SkeletalInfo)
UFUNCTION(Unreliable, Server, WithValidation)
 
USTRUCT(BlueprintType, Category = "VRExpansionFunctions|OpenXR|HandSkeleton")
 
TArray< FTransform > OldSkeletalTransforms
UPROPERTY(BlueprintReadOnly, NotReplicated, Transient, Category = Default)
 
TArray< FTransform > SkeletalTransforms
UPROPERTY(BlueprintReadOnly, NotReplicated, Transient, Category = Default)
 
bool bEnableUE4HandRepSavings
UPROPERTY(EditAnywhere, NotReplicated, BlueprintReadWrite, Category = Default)
 
EVRSkeletalHandIndex TargetHand
UPROPERTY(EditAnywhere, NotReplicated, BlueprintReadWrite, Category = Default)
 
bool bHasValidData
UPROPERTY(NotReplicated, BlueprintReadOnly, Category = Default)
 
int32 LastHandGestureIndex
 
USTRUCT(BlueprintType, Category = "VRExpansionFunctions|SteamVR|HandSkeleton")
 
USTRUCT(BlueprintType, Category = "VRExpansionFunctions|SteamVR|HandSkeleton")
 
USTRUCT(BlueprintType, Category = "VRExpansionFunctions|OpenXR|HandSkeleton")
 
EVRSkeletalHandIndex TargetHand
UPROPERTY(Transient, NotReplicated)
 
bool bEnableUE4HandRepSavings
UPROPERTY(Transient, NotReplicated)
 
bool bAllowDeformingMesh
UPROPERTY(Transient, NotReplicated)
 
TArray< FTransform > SkeletalTransforms
UPROPERTY(Transient, NotReplicated)
 
void CopyForReplication(FBPOpenXRActionSkeletalData &Other)
 
static void CopyReplicatedTo(const FBPSkeletalRepContainer &Container, FBPOpenXRActionSkeletalData &Other)
 
bool NetSerialize(FArchive &Ar, class UPackageMap *Map, bool &bOutSuccess)
 
TArray< FBPOpenXRActionSkeletalData > HandSkeletalActionData
 
virtual void PreUpdate(UAnimInstance *InAnimInstance, float DeltaSeconds) override
 
FOpenXRAnimInstanceProxy()
 
USTRUCT(BlueprintType, Category = "VRGestures")
 
USTRUCT(BlueprintType, Category = "VRGestures")
 
FName Name
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VRGesture")
 
TArray< FOpenXRGestureFingerPosition > FingerValues
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VRGesture")