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")