refactor the animation, wrist tracking, and hand interaction manipulation systems for FXRMotionControllerData compatibility

This commit is contained in:
Mamadou Babaei
2024-08-16 16:29:36 +02:00
parent dccf6ad013
commit 84315e146f
16 changed files with 425 additions and 341 deletions
@@ -73,20 +73,17 @@ void FSGVirtualHandAnimInstanceProxy::PreEvaluateAnimation(UAnimInstance* InAnim
return;
}
BonesRotations.Empty();
if (!VirtualHand->IsGloveConnected())
const bool bGotMotionControllerData = VirtualHand->GetMotionControllerData(MotionControllerData);
if (!bGotMotionControllerData || !MotionControllerData.bValid)
{
return;
}
BonesRotations = VirtualHand->GetFingersBonesRotations();
}
bool FSGVirtualHandAnimInstanceProxy::Evaluate(FPoseContext& Output)
{
USGVirtualHandComponent* VirtualHand{Cast<USGVirtualHandComponent>(GetSkelMeshComponent())};
if (!IsValid(VirtualHand) && !VirtualHand->IsGloveConnected())
if (!IsValid(VirtualHand))
{
return FAnimInstanceProxy::Evaluate(Output);
}
@@ -103,19 +100,33 @@ bool FSGVirtualHandAnimInstanceProxy::Evaluate(FPoseContext& Output)
return FAnimInstanceProxy::Evaluate(Output);
}
if (!MotionControllerData.bValid)
{
return FAnimInstanceProxy::Evaluate(Output);
}
ensureAlwaysMsgf(MotionControllerData.HandKeyPositions.Num() == MotionControllerData.HandKeyRotations.Num(),
TEXT("Mismatched motion controller data positions and rotations!"));
const FRotator& AnimationBoneRotationCorrectionOffset{VirtualHand->GetAnimationBoneRotationCorrectionOffset()};
const FTransform AnimationBoneCorrectionOffsetTransform{AnimationBoneRotationCorrectionOffset};
const bool bAnimationShouldApplyBoneLocation = VirtualHand->AnimationShouldApplyBoneLocation();
FComponentSpacePoseContext PoseContext{Output.AnimInstanceProxy};
PoseContext.Pose.InitPose(Output.Pose);
for (const TTuple<FName, FRotator>& Bone: BonesRotations)
for (TArray<FQuat>::SizeType HandKeyIndex = 0;
HandKeyIndex < MotionControllerData.HandKeyRotations.Num(); ++HandKeyIndex)
{
FName BoneName{Bone.Key};
FRotator BoneRotation{Bone.Value};
FName BoneName{VirtualHand->GetHandBoneName(HandKeyIndex)};
if (BoneName == NAME_None)
{
continue;
}
const int32 BoneIndex = GetRequiredBones().GetPoseBoneIndexForBoneName(BoneName);
if (BoneIndex == INDEX_NONE)
{
SGLOG_WARNING(FString::Printf(TEXT("Could not find a bone index for '%s' finger bone!"),
*BoneName.ToString()));
continue;
}
@@ -124,27 +135,50 @@ bool FSGVirtualHandAnimInstanceProxy::Evaluate(FPoseContext& Output)
BoneReference.BoneIndex = BoneIndex;
BoneReference.bUseSkeletonIndex = true;
const FVector& HandKeyPosition{MotionControllerData.HandKeyPositions[HandKeyIndex]};
const FQuat& HandKeyRotation{MotionControllerData.HandKeyRotations[HandKeyIndex]};
const FTransform HandKeyTransform{HandKeyRotation, HandKeyPosition};
const FTransform BoneTransform{AnimationBoneCorrectionOffsetTransform * HandKeyTransform};
FRotator BoneRotation{BoneTransform.GetRotation().Rotator()};
FAnimNode_ModifyBone BoneController;
BoneController.BoneToModify = MoveTemp(BoneReference);
BoneController.Rotation = MoveTemp(BoneRotation);
BoneController.RotationMode = EBoneModificationMode::BMM_Replace;
BoneController.RotationSpace = EBoneControlSpace::BCS_ParentBoneSpace;
BoneController.RotationSpace = EBoneControlSpace::BCS_WorldSpace;
BoneController.ScaleMode = EBoneModificationMode::BMM_Ignore;
BoneController.TranslationMode = EBoneModificationMode::BMM_Ignore;
if (BoneController.IsValidToEvaluate(HandSkeleton, Output.Pose.GetBoneContainer()))
if (bAnimationShouldApplyBoneLocation)
{
TArray<FBoneTransform> BoneTransforms;
BoneController.EvaluateSkeletalControl_AnyThread(PoseContext, BoneTransforms);
FVector BoneTranslation{BoneTransform.GetLocation()};
BoneController.TranslationMode = EBoneModificationMode::BMM_Replace;
BoneController.TranslationSpace = EBoneControlSpace::BCS_WorldSpace;
BoneController.Translation = MoveTemp(BoneTranslation);
}
else
{
BoneController.TranslationMode = EBoneModificationMode::BMM_Ignore;
}
const TArray<FBoneTransform>::SizeType BoneTransformsNum = BoneTransforms.Num();
if (BoneTransformsNum > 0)
{
PoseContext.Pose.LocalBlendCSBoneTransforms(BoneTransforms, 1.0f);
PoseContext.Pose.ConvertComponentPosesToLocalPoses(PoseContext.Pose, Output.Pose);
const bool bValidToEvaluate =
BoneController.IsValidToEvaluate(HandSkeleton, Output.Pose.GetBoneContainer());
if (!bValidToEvaluate)
{
continue;
}
VirtualHand->MarkRenderStateDirty();
}
TArray<FBoneTransform> BoneTransforms;
BoneController.EvaluateSkeletalControl_AnyThread(PoseContext, BoneTransforms);
const TArray<FBoneTransform>::SizeType BoneTransformsNum = BoneTransforms.Num();
if (BoneTransformsNum > 0)
{
PoseContext.Pose.LocalBlendCSBoneTransforms(BoneTransforms, 1.0f);
PoseContext.Pose.ConvertComponentPosesToLocalPoses(PoseContext.Pose, Output.Pose);
/// FIXME
// This causes a data race in the refactored code!
//VirtualHand->MarkRenderStateDirty();
}
}
@@ -35,15 +35,18 @@
#include "SenseGlove/Components/SGVirtualHandComponent.h"
#include "HeadMountedDisplayTypes.h"
#include "Animation/Skeleton.h"
#include "Components/SkeletalMeshComponent.h"
#include "Engine/Engine.h"
#include "Engine/SkeletalMesh.h"
#include "InputCoreTypes.h"
#include "IXRTrackingSystem.h"
#include "Templates/UnrealTypeTraits.h"
#include "UObject/ConstructorHelpers.h"
#include "SenseGlove/Animation/SGVirtualHandAnimInstance.h"
#include "SenseGlove/Components/SGWristTrackerComponent.h"
#include "SGCore/SGHandPose.h"
#include "SGCore/SGHapticGlove.h"
#include "SGDebug/SGDebugVirtualHand.h"
#include "SGLog/SGLog.h"
@@ -129,49 +132,89 @@ struct USGVirtualHandComponent::FImpl
void DrawDebugVirtualHand() const;
};
const TArray<TArray<FName>>& USGVirtualHandComponent::GetLeftHandFingerBoneNames()
const TArray<FName>& USGVirtualHandComponent::GetLeftHandBoneNames()
{
static const TArray<TArray<FName>> BoneNames{
{FName(TEXT("thumb_01_l")), FName(TEXT("thumb_02_l")), FName(TEXT("thumb_03_l"))},
{FName(TEXT("index_01_l")), FName(TEXT("index_02_l")), FName(TEXT("index_03_l"))},
{FName(TEXT("middle_01_l")), FName(TEXT("middle_02_l")), FName(TEXT("middle_03_l"))},
{FName(TEXT("ring_01_l")), FName(TEXT("ring_02_l")), FName(TEXT("ring_03_l"))},
{FName(TEXT("pinky_01_l")), FName(TEXT("pinky_02_l")), FName(TEXT("pinky_03_l"))},
static const TArray<FName> BoneNames{
FName{TEXT("palm_l")},// Palm
FName{TEXT("hand_l")},// Wrist
FName{TEXT("thumb_01_l")},// ThumbMetacarpal
FName{TEXT("thumb_02_l")},// ThumbProximal
FName{TEXT("thumb_03_l")},// ThumbDistal
NAME_None,// ThumbTip
FName{TEXT("index_metacarpal_l")},// IndexMetacarpal
FName{TEXT("index_01_l")},// IndexProximal
FName{TEXT("index_02_l")},// IndexIntermediate
FName{TEXT("index_03_l")},// IndexDistal
NAME_None,// IndexTip
FName{TEXT("middle_metacarpal_l")},// MiddleMetacarpal
FName{TEXT("middle_01_l")},// MiddleProximal
FName{TEXT("middle_02_l")},// MiddleIntermediate
FName{TEXT("middle_03_l")},// MiddleDistal
NAME_None,// MiddleTip
FName{TEXT("ring_metacarpal_l")},// RingMetacarpal
FName{TEXT("ring_01_l")},// RingProximal
FName{TEXT("ring_02_l")},// RingIntermediate
FName{TEXT("ring_03_l")},// RingDistal
NAME_None,// RingTip
FName{TEXT("pinky_metacarpal_l")},// LittleMetacarpal
FName{TEXT("pinky_01_l")},// LittleProximal
FName{TEXT("pinky_02_l")},// LittleIntermediate
FName{TEXT("pinky_03_l")},// LittleDistal
NAME_None,// LittleTip
};
return BoneNames;
}
const TArray<TArray<FName>>& USGVirtualHandComponent::GetRightHandFingerBoneNames()
const TArray<FName>& USGVirtualHandComponent::GetRightHandBoneNames()
{
static const TArray<TArray<FName>> BoneNames{
{FName(TEXT("thumb_01_r")), FName(TEXT("thumb_02_r")), FName(TEXT("thumb_03_r"))},
{FName(TEXT("index_01_r")), FName(TEXT("index_02_r")), FName(TEXT("index_03_r"))},
{FName(TEXT("middle_01_r")), FName(TEXT("middle_02_r")), FName(TEXT("middle_03_r"))},
{FName(TEXT("ring_01_r")), FName(TEXT("ring_02_r")), FName(TEXT("ring_03_r"))},
{FName(TEXT("pinky_01_r")), FName(TEXT("pinky_02_r")), FName(TEXT("pinky_03_r"))},
static const TArray<FName> BoneNames{
FName{TEXT("palm_r")},// Palm
FName{TEXT("hand_r")},// Wrist
FName{TEXT("thumb_01_r")},// ThumbMetacarpal
FName{TEXT("thumb_02_r")},// ThumbProximal
FName{TEXT("thumb_03_r")},// ThumbDistal
NAME_None,// ThumbTip
FName{TEXT("index_metacarpal_r")},// IndexMetacarpal
FName{TEXT("index_01_r")},// IndexProximal
FName{TEXT("index_02_r")},// IndexIntermediate
FName{TEXT("index_03_r")},// IndexDistal
NAME_None,// IndexTip
FName{TEXT("middle_metacarpal_r")},// MiddleMetacarpal
FName{TEXT("middle_01_r")},// MiddleProximal
FName{TEXT("middle_02_r")},// MiddleIntermediate
FName{TEXT("middle_03_r")},// MiddleDistal
NAME_None,// MiddleTip
FName{TEXT("ring_metacarpal_r")},// RingMetacarpal
FName{TEXT("ring_01_r")},// RingProximal
FName{TEXT("ring_02_r")},// RingIntermediate
FName{TEXT("ring_03_r")},// RingDistal
NAME_None,// RingTip
FName{TEXT("pinky_metacarpal_r")},// LittleMetacarpal
FName{TEXT("pinky_01_r")},// LittleProximal
FName{TEXT("pinky_02_r")},// LittleIntermediate
FName{TEXT("pinky_03_r")},// LittleDistal
NAME_None,// LittleTip
};
return BoneNames;
}
const FName& USGVirtualHandComponent::GetLeftHandFingerBoneName(const int32 Finger, const int32 Joint)
const FName& USGVirtualHandComponent::GetLeftHandBoneName(const int32 Joint)
{
const TArray<TArray<FName>>& BoneNames{GetLeftHandFingerBoneNames()};
const TArray<FName>& BoneNames{GetLeftHandBoneNames()};
ensureAlwaysMsgf(Finger < BoneNames.Num(), TEXT("Finger index is out of bound!"));
ensureAlwaysMsgf(Joint < BoneNames[Finger].Num(), TEXT("Joint index is out of bound!"));
ensureAlwaysMsgf(Joint < BoneNames.Num(), TEXT("Joint index is out of bound!"));
const FName& BoneName{BoneNames[Finger][Joint]};
const FName& BoneName{BoneNames[Joint]};
return BoneName;
}
const FName& USGVirtualHandComponent::GetRightHandFingerBoneName(const int32 Finger, const int32 Joint)
const FName& USGVirtualHandComponent::GetRightHandBoneName(const int32 Joint)
{
const TArray<TArray<FName>>& BoneNames{GetRightHandFingerBoneNames()};
const TArray<FName>& BoneNames{GetRightHandBoneNames()};
ensureAlwaysMsgf(Finger < BoneNames.Num(), TEXT("Finger index is out of bound!"));
ensureAlwaysMsgf(Joint < BoneNames[Finger].Num(), TEXT("Joint index is out of bound!"));
ensureAlwaysMsgf(Joint < BoneNames.Num(), TEXT("Joint index is out of bound!"));
const FName& BoneName{BoneNames[Finger][Joint]};
const FName& BoneName{BoneNames[Joint]};
return BoneName;
}
@@ -207,7 +250,10 @@ USGVirtualHandComponent::USGVirtualHandComponent(const FObjectInitializer& Objec
Super::SetAnimClass(USGVirtualHandAnimInstance::StaticClass());
bRight = true;
bHiddenInGameIfNoGloveDetected = false;
bHiddenInGameIfNoHandDataAvailable = false;
AnimationBoneRotationCorrectionOffset = FRotator{0.0f, 90.0f, 90.0f};
bAnimationShouldApplyBoneLocation = true;
bAutoStopAllHapticsOnEndPlay = true;
@@ -300,7 +346,7 @@ void USGVirtualHandComponent::UninitializeComponent()
const USGGloveTracker* GloveTracker{USGGloveTracker::GetInstance()};
USGHapticGlove* Glove{IsValid(GloveTracker) ? GloveTracker->GetGlove(IsRight()) : nullptr};
if (IsValid(Glove) && AutoStopsAllHapticsOnEndPlay())
if (IsValid(Glove) && Glove->IsConnected() && AutoStopsAllHapticsOnEndPlay())
{
Glove->StopHaptics();
}
@@ -319,7 +365,7 @@ void USGVirtualHandComponent::EndPlay(const EEndPlayReason::Type EndPlayReason)
const USGGloveTracker* GloveTracker{USGGloveTracker::GetInstance()};
USGHapticGlove* Glove{IsValid(GloveTracker) ? GloveTracker->GetGlove(IsRight()) : nullptr};
if (IsValid(Glove) && AutoStopsAllHapticsOnEndPlay())
if (IsValid(Glove) && Glove->IsConnected() && AutoStopsAllHapticsOnEndPlay())
{
Glove->StopHaptics();
}
@@ -340,9 +386,7 @@ void USGVirtualHandComponent::TickComponent(
Pimpl->UpdateGloveVisibility();
const USGGloveTracker* GloveTracker{USGGloveTracker::GetInstance()};
USGHapticGlove* Glove{IsValid(GloveTracker) ? GloveTracker->GetGlove(IsRight()) : nullptr};
if (IsValid(Glove) && DebugVirtualHandSettings.DrawingMode != ESGDebugVirtualHandDrawingMode::None)
if (DebugVirtualHandSettings.DrawingMode != ESGDebugVirtualHandDrawingMode::None)
{
Pimpl->DrawDebugVirtualHand();
}
@@ -365,9 +409,7 @@ void USGVirtualHandComponent::EditorTick(
{
Pimpl->UpdateGloveVisibility();
const USGGloveTracker* GloveTracker{USGGloveTracker::GetInstance()};
USGHapticGlove* Glove{IsValid(GloveTracker) ? GloveTracker->GetGlove(IsRight()) : nullptr};
if (IsValid(Glove) && DebugVirtualHandSettings.DrawingMode != ESGDebugVirtualHandDrawingMode::None)
if (DebugVirtualHandSettings.DrawingMode != ESGDebugVirtualHandDrawingMode::None)
{
Pimpl->DrawDebugVirtualHand();
}
@@ -387,39 +429,51 @@ USGHapticGlove* USGVirtualHandComponent::GetConnectedGlove() const
return Glove;
}
USGHandPose* USGVirtualHandComponent::GetHandPose()
bool USGVirtualHandComponent::GetMotionControllerData(FXRMotionControllerData& OutMotionControllerData)
{
USGHandPose* HandPose{nullptr};
OutMotionControllerData.bValid = false;
const USGGloveTracker* GloveTracker{USGGloveTracker::GetInstance()};
USGHapticGlove* Glove{IsValid(GloveTracker) ? GloveTracker->GetGlove(IsRight()) : nullptr};
if (IsValid(Glove))
if (GEngine)
{
Glove->GetHandPose(this, HandPose);
IXRTrackingSystem* XrtTrackingSystem = GEngine->XRSystem.Get();
if (XrtTrackingSystem)
{
const EControllerHand Hand = IsRight() ? EControllerHand::Right : EControllerHand::Left;
XrtTrackingSystem->GetMotionControllerData(this, Hand, OutMotionControllerData);
}
}
return HandPose;
return OutMotionControllerData.bValid;
}
const FName& USGVirtualHandComponent::GetFingerBoneName(const int32 Finger, const int32 Joint) const
const TArray<FName>& USGVirtualHandComponent::GetHandBoneNames() const
{
const TArray<FName>& Names{
IsRight()
? GetRightHandBoneNames()
: GetLeftHandBoneNames()
};
return Names;
}
const FName& USGVirtualHandComponent::GetHandBoneName(const int32 Joint) const
{
const FName& Name{
IsRight()
? GetRightHandFingerBoneName(Finger, Joint)
: GetLeftHandFingerBoneName(Finger, Joint)
? GetRightHandBoneName(Joint)
: GetLeftHandBoneName(Joint)
};
return Name;
}
const FTransform& USGVirtualHandComponent::GetFingerBoneRefTransform(const int32 Finger, const int32 Joint) const
const FTransform& USGVirtualHandComponent::GetHandBoneRefTransform(const FName& BoneName) const
{
const FName& BoneName{GetFingerBoneName(Finger, Joint)};
const FReferenceSkeleton& ReferenceSkeleton{Pimpl->GetRefSkeleton()};
const int32 BoneIndex = ReferenceSkeleton.FindBoneIndex(BoneName);
if (BoneIndex == INDEX_NONE)
{
SGLOG_WARNING(FString::Printf(TEXT("Could not find a bone index for '%s' finger bone!"),
SGLOG_WARNING(FString::Printf(TEXT("Could not find a bone index for the '%s' joint!"),
*BoneName.ToString()));
return FTransform::Identity;
}
@@ -428,50 +482,31 @@ const FTransform& USGVirtualHandComponent::GetFingerBoneRefTransform(const int32
return BoneTransform;
}
FRotator USGVirtualHandComponent::GetFingerBoneRefRotation(const int32 Finger, const int32 Joint) const
const FTransform& USGVirtualHandComponent::GetHandRootBoneRefTransform() const
{
const FTransform BoneTransform{GetFingerBoneRefTransform(Finger, Joint)};
static constexpr int32_t WristKeypointIndex = static_cast<int32>(EHandKeypoint::Wrist);
const FTransform& BoneTransform{GetHandBoneRefTransform(WristKeypointIndex)};
return BoneTransform;
}
const FTransform& USGVirtualHandComponent::GetHandBoneRefTransform(const int32 Joint) const
{
const FName& BoneName{GetHandBoneName(Joint)};
return GetHandBoneRefTransform(BoneName);
}
FRotator USGVirtualHandComponent::GetHandBoneRefRotation(const FName& BoneName) const
{
const FTransform BoneTransform{GetHandBoneRefTransform(BoneName)};
const FRotator BoneRotation{BoneTransform.GetRotation().Rotator()};
return BoneRotation;
}
TMap<FName, FRotator> USGVirtualHandComponent::GetFingersBonesRotations()
FRotator USGVirtualHandComponent::GetHandBoneRefRotation(const int32 Joint) const
{
TMap<FName, FRotator> Rotations;
if (!IsGloveConnected())
{
return Rotations;
}
const USGHandPose* HandPose = GetHandPose();
if (!IsValid(HandPose))
{
return Rotations;
}
const TArray<TArray<FVector>>& HandAngles{HandPose->GetHandAngles()};
for (int32 FingerIndex = 0; FingerIndex < HandAngles.Num(); ++FingerIndex)
{
const TArray<FVector>& FingerJointAngles{HandAngles[FingerIndex]};
for (int32 JointIndex = 0; JointIndex < FingerJointAngles.Num(); ++JointIndex)
{
const FVector& JointAngle{FingerJointAngles[JointIndex]};
const FQuat JointRotation{FQuat::MakeFromEuler(FVector{-JointAngle.Y, -JointAngle.X, -JointAngle.Z})};
const FTransform& BoneRefTransform{GetFingerBoneRefTransform(FingerIndex, JointIndex)};
FQuat NewBoneRotation{BoneRefTransform.GetRotation() * JointRotation};
FName BoneName{GetFingerBoneName(FingerIndex, JointIndex)};
Rotations.Emplace(MoveTemp(BoneName), MoveTemp(NewBoneRotation));
}
}
return Rotations;
const FTransform BoneTransform{GetHandBoneRefTransform(Joint)};
const FRotator BoneRotation{BoneTransform.GetRotation().Rotator()};
return BoneRotation;
}
USGVirtualHandComponent::FImpl::FImpl(USGVirtualHandComponent* InOwner)
@@ -516,11 +551,11 @@ bool USGVirtualHandComponent::FImpl::IsUsingDefaultMesh() const
return false;
}
const FString CurrentMeshPath(CurrentMesh->GetPathName());
const FString LeftHandDefaultMeshPath(GetDefaultLeftHandMeshPath());
const FString LeftHandDefaultMeshPathOnly(GetDefaultLeftHandMeshPathOnly());
const FString RightHandDefaultMeshPath(GetDefaultRightHandMeshPath());
const FString RightHandDefaultMeshPathOnly(GetDefaultRightHandMeshPathOnly());
const FString CurrentMeshPath{CurrentMesh->GetPathName()};
const FString LeftHandDefaultMeshPath{GetDefaultLeftHandMeshPath()};
const FString LeftHandDefaultMeshPathOnly{GetDefaultLeftHandMeshPathOnly()};
const FString RightHandDefaultMeshPath{GetDefaultRightHandMeshPath()};
const FString RightHandDefaultMeshPathOnly{GetDefaultRightHandMeshPathOnly()};
if (CurrentMeshPath == LeftHandDefaultMeshPath
|| CurrentMeshPath == LeftHandDefaultMeshPathOnly
|| CurrentMeshPath == RightHandDefaultMeshPath
@@ -540,11 +575,11 @@ bool USGVirtualHandComponent::FImpl::IsUsingUserMesh() const
return false;
}
const FString CurrentMeshPath(CurrentMesh->GetPathName());
const FString LeftHandDefaultMeshPath(GetDefaultLeftHandMeshPath());
const FString LeftHandDefaultMeshPathOnly(GetDefaultLeftHandMeshPathOnly());
const FString RightHandDefaultMeshPath(GetDefaultRightHandMeshPath());
const FString RightHandDefaultMeshPathOnly(GetDefaultRightHandMeshPathOnly());
const FString CurrentMeshPath{CurrentMesh->GetPathName()};
const FString LeftHandDefaultMeshPath{GetDefaultLeftHandMeshPath()};
const FString LeftHandDefaultMeshPathOnly{GetDefaultLeftHandMeshPathOnly()};
const FString RightHandDefaultMeshPath{GetDefaultRightHandMeshPath()};
const FString RightHandDefaultMeshPathOnly{GetDefaultRightHandMeshPathOnly()};
if (CurrentMeshPath == LeftHandDefaultMeshPath
|| CurrentMeshPath == LeftHandDefaultMeshPathOnly
|| CurrentMeshPath == RightHandDefaultMeshPath
@@ -597,15 +632,14 @@ const FReferenceSkeleton& USGVirtualHandComponent::FImpl::GetRefSkeleton() const
void USGVirtualHandComponent::FImpl::UpdateGloveVisibility() const
{
const USGGloveTracker* GloveTracker{USGGloveTracker::GetInstance()};
const USGHapticGlove* Glove{IsValid(GloveTracker) ? GloveTracker->GetGlove(Owner->IsRight()) : nullptr};
const bool bConnected = IsValid(Glove);
FXRMotionControllerData MotionControllerData;
const bool bGotMotionControllerData = Owner->GetMotionControllerData(MotionControllerData);
const bool bIsHandDataAvailable = bGotMotionControllerData && MotionControllerData.bValid;
const bool bIsVisible = Owner->IsVisible();
if (Owner->bHiddenInGameIfNoGloveDetected)
if (Owner->bHiddenInGameIfNoHandDataAvailable)
{
if (bConnected)
if (bIsHandDataAvailable)
{
if (!bIsVisible)
{
@@ -638,20 +672,14 @@ void USGVirtualHandComponent::FImpl::DrawDebugVirtualHand() const
return;
}
const FVector& WristLocation{Owner->WristTracker->GetWristLocation()};
const FRotator& WristRotation{Owner->WristTracker->GetWristRotation()};
const USGHandPose* HandPose{Owner->GetHandPose()};
if (!IsValid(HandPose))
FXRMotionControllerData MotionControllerData;
const bool bGotMotionControllerData{Owner->GetMotionControllerData(MotionControllerData)};
if (!bGotMotionControllerData || !MotionControllerData.bValid)
{
return;
}
const TArray<TArray<FVector>>& JointPositions{HandPose->GetJointPositions()};
const TArray<TArray<FRotator>>& JointRotations{HandPose->GetJointRotations()};
FSGDebugVirtualHand::Draw(World, WristLocation, WristRotation, JointPositions, JointRotations,
Owner->DebugVirtualHandSettings);
FSGDebugVirtualHand::Draw(World, MotionControllerData, Owner->DebugVirtualHandSettings);
}
void USGVirtualHandComponent::FImplDeleter::operator()(const FImpl* P) const
@@ -40,12 +40,9 @@
#include "Engine/SkeletalMesh.h"
#include "UObject/ConstructorHelpers.h"
#include "SGCore/SGHapticGlove.h"
#include "SGDebug/SGDebugGizmo.h"
#include "SGLog/SGLog.h"
#include "SGSettings/SGSettings.h"
#include "SGTracking/SGGloveTracker.h"
#include "SGTracking/SGHMDTracker.h"
struct USGWristTrackerComponent::FImpl
{
@@ -233,62 +230,8 @@ void USGWristTrackerComponent::FImpl::UpdateMotionSource() const
void USGWristTrackerComponent::FImpl::UpdateWristTrackingData() const
{
const USGGloveTracker* GloveTracker{USGGloveTracker::GetInstance()};
const USGHapticGlove* Glove{IsValid(GloveTracker) ? GloveTracker->GetGlove(Owner->IsRight()) : nullptr};
if (!IsValid(Glove))
{
return;
}
FVector TrackerLocation{Owner->GetComponentLocation()};
FRotator TrackerRotation{Owner->GetComponentRotation()};
ESGPositionalTrackingHardware TrackerHardware = Owner->GetWristTrackingSettings().TrackingHardware;
if (TrackerHardware == ESGPositionalTrackingHardware::None)
{
const ESGHeadMountedDisplayDevice HmdDevice = FSGHMDTracker::GetDeviceType();
switch (HmdDevice)
{
case ESGHeadMountedDisplayDevice::MetaQuest2:
TrackerHardware = ESGPositionalTrackingHardware::Quest2Controller;
break;
case ESGHeadMountedDisplayDevice::MetaQuestPro:
TrackerHardware = ESGPositionalTrackingHardware::QuestProController;
break;
case ESGHeadMountedDisplayDevice::MetaQuest3:
TrackerHardware = ESGPositionalTrackingHardware::Quest3Controller;
break;
case ESGHeadMountedDisplayDevice::HtcVivePro:
TrackerHardware = ESGPositionalTrackingHardware::ViveTracker;
break;
case ESGHeadMountedDisplayDevice::HtcViveFocus3:
// Fall through
case ESGHeadMountedDisplayDevice::HtcViveXRElite:
TrackerHardware = ESGPositionalTrackingHardware::ViveFocus3WristTracker;
break;
default:
TrackerHardware = ESGPositionalTrackingHardware::Custom;
break;
}
}
else if (TrackerHardware == ESGPositionalTrackingHardware::Custom)
{
if (Owner->IsRight())
{
TrackerLocation += Owner->GetWristTrackingSettings().TrackingHardwareLocationOffsetRightHand;
TrackerRotation += Owner->GetWristTrackingSettings().TrackingHardwareRotationOffsetRightHand;
}
else
{
TrackerLocation += Owner->GetWristTrackingSettings().TrackingHardwareLocationOffsetLeftHand;
TrackerRotation += Owner->GetWristTrackingSettings().TrackingHardwareRotationOffsetLeftHand;
}
}
FVector NewWristLocation;
FRotator NewWristRotation;
Glove->GetWristLocation(TrackerLocation, TrackerRotation, TrackerHardware,
NewWristLocation, NewWristRotation);
FVector NewWristLocation{Owner->GetComponentLocation()};
FRotator NewWristRotation{Owner->GetComponentRotation()};
const bool bLocationUpdated = !Owner->WristLocation.Equals(NewWristLocation, SMALL_NUMBER);
const bool bRotationUpdated = !Owner->WristRotation.Equals(NewWristRotation, SMALL_NUMBER);
@@ -202,7 +202,7 @@ ASGPawn::ASGPawn(const FObjectInitializer& ObjectInitializer)
HandLeft->SetCollisionResponseToChannel(ECC_Vehicle, ECR_Block);
HandLeft->SetCollisionResponseToChannel(ECC_Destructible, ECR_Block);
HandLeft->SetRight(false);
HandLeft->SetHiddenIfNoGloveDetected(true);
HandLeft->SetHiddenIfNoHandDataAvailable(true);
HandLeft->SetRelativeRotation(FRotator{0.0f, SG_HAND_MESH_YAW_CORRECTION_OFFSET, 0.0f},
false, nullptr, ETeleportType::None);
HandLeft->SetRelativeLocation(FVector{30.0f, -20.0f, -10.0f},
@@ -226,7 +226,7 @@ ASGPawn::ASGPawn(const FObjectInitializer& ObjectInitializer)
RealHandLeft->SetCollisionResponseToChannel(ECC_Destructible, ECR_Overlap);
RealHandLeft->SetRight(false);
Pimpl->SetVisibility(RealHandLeft, false);
RealHandLeft->SetHiddenIfNoGloveDetected(true);
RealHandLeft->SetHiddenIfNoHandDataAvailable(true);
RealHandLeft->SetRelativeRotation(FRotator{0.0f, SG_HAND_MESH_YAW_CORRECTION_OFFSET, 0.0f},
false, nullptr, ETeleportType::None);
RealHandLeft->SetRelativeLocation(FVector{30.0f, -20.0f, -10.0f},
@@ -428,7 +428,7 @@ ASGPawn::ASGPawn(const FObjectInitializer& ObjectInitializer)
HandRight->SetCollisionResponseToChannel(ECC_Vehicle, ECR_Block);
HandRight->SetCollisionResponseToChannel(ECC_Destructible, ECR_Block);
HandRight->SetRight(true);
HandRight->SetHiddenIfNoGloveDetected(true);
HandRight->SetHiddenIfNoHandDataAvailable(true);
HandRight->SetRelativeRotation(FRotator{0.0f, SG_HAND_MESH_YAW_CORRECTION_OFFSET, 0.0f},
false, nullptr, ETeleportType::None);
HandRight->SetRelativeLocation(FVector{30.0f, 20.0f, -10.0f},
@@ -452,7 +452,7 @@ ASGPawn::ASGPawn(const FObjectInitializer& ObjectInitializer)
RealHandRight->SetCollisionResponseToChannel(ECC_Destructible, ECR_Overlap);
RealHandRight->SetRight(true);
Pimpl->SetVisibility(RealHandRight, false);
RealHandRight->SetHiddenIfNoGloveDetected(true);
RealHandRight->SetHiddenIfNoHandDataAvailable(true);
RealHandRight->SetRelativeRotation(FRotator{0.0f, SG_HAND_MESH_YAW_CORRECTION_OFFSET, 0.0f},
false, nullptr, ETeleportType::None);
RealHandRight->SetRelativeLocation(FVector{30.0f, 20.0f, -10.0f},
@@ -36,6 +36,7 @@
#pragma once
#include "Animation/AnimInstanceProxy.h"
#include "HeadMountedDisplayTypes.h"
#include "Templates/UniquePtr.h"
#include "UObject/NameTypes.h"
@@ -47,16 +48,16 @@ struct SENSEGLOVE_API FSGVirtualHandAnimInstanceProxy : public FAnimInstanceProx
GENERATED_USTRUCT_BODY()
private:
TMap<FName, FRotator> BonesRotations;
FXRMotionControllerData MotionControllerData;
public:
FSGVirtualHandAnimInstanceProxy();
FSGVirtualHandAnimInstanceProxy(UAnimInstance* Instance);
public:
FORCEINLINE const TMap<FName, FRotator>& GetBonesRotations() const
protected:
FORCEINLINE const FXRMotionControllerData& GetMotionControllerData() const
{
return BonesRotations;
return MotionControllerData;
}
protected:
@@ -39,6 +39,7 @@
#include "Components/SkeletalMeshComponent.h"
#include "Containers/Map.h"
#include "GameFramework/Actor.h"
#include "HeadMountedDisplayTypes.h"
#include "Math/Rotator.h"
#include "Math/Transform.h"
#include "ReferenceSkeleton.h"
@@ -52,7 +53,6 @@
class USphereComponent;
class USkeletalMesh;
class USGHandPose;
class USGHapticGlove;
class USGWristTrackerComponent;
@@ -63,11 +63,11 @@ class SENSEGLOVE_API USGVirtualHandComponent : public USkeletalMeshComponent
GENERATED_UCLASS_BODY()
public:
static const TArray<TArray<FName>>& GetLeftHandFingerBoneNames();
static const TArray<TArray<FName>>& GetRightHandFingerBoneNames();
static const TArray<FName>& GetLeftHandBoneNames();
static const TArray<FName>& GetRightHandBoneNames();
static const FName& GetLeftHandFingerBoneName(int32 Finger, int32 Joint);
static const FName& GetRightHandFingerBoneName(int32 Finger, int32 Joint);
static const FName& GetLeftHandBoneName(int32 Joint);
static const FName& GetRightHandBoneName(int32 Joint);
private:
struct FImpl;
@@ -85,7 +85,13 @@ private:
uint8 bRight : 1;
UPROPERTY(EditAnywhere, Category="SenseGlove", meta=(AllowPrivateAccess="false"))
uint8 bHiddenInGameIfNoGloveDetected : 1;
uint8 bHiddenInGameIfNoHandDataAvailable : 1;
UPROPERTY(EditAnywhere, Category="SenseGlove | Animation", meta=(AllowPrivateAccess="false"))
FRotator AnimationBoneRotationCorrectionOffset;
UPROPERTY(EditAnywhere, Category="SenseGlove | Animation", meta=(AllowPrivateAccess="false"))
uint8 bAnimationShouldApplyBoneLocation : 1;
UPROPERTY(EditAnywhere, Category="SenseGlove | Haptics", meta=(AllowPrivateAccess="false"))
uint8 bAutoStopAllHapticsOnEndPlay : 1;
@@ -153,6 +159,27 @@ public:
MiddleFingertipTouchSocketName = SocketName;
}
FORCEINLINE const FRotator& GetAnimationBoneRotationCorrectionOffset() const
{
return AnimationBoneRotationCorrectionOffset;
}
FORCEINLINE void SetAnimationBoneRotationCorrectionOffset(
const FRotator& InAnimationBoneRotationCorrectionOffset)
{
AnimationBoneRotationCorrectionOffset = InAnimationBoneRotationCorrectionOffset;
}
FORCEINLINE bool AnimationShouldApplyBoneLocation() const
{
return !!bAnimationShouldApplyBoneLocation;
}
FORCEINLINE void SetAnimationShouldApplyBoneLocation(const bool bInAnimationShouldApplyBoneLocation)
{
bAnimationShouldApplyBoneLocation = bInAnimationShouldApplyBoneLocation;
}
FORCEINLINE bool AutoStopsAllHapticsOnEndPlay() const
{
return !!bAutoStopAllHapticsOnEndPlay;
@@ -263,14 +290,14 @@ public:
DebugVirtualHandSettings = InDebugVirtualHandSettings;
}
FORCEINLINE bool IsHiddenInGameIfNoGloveDetected() const
FORCEINLINE bool IsHiddenInGameIfNoHandDataAvailable() const
{
return !!bHiddenInGameIfNoGloveDetected;
return !!bHiddenInGameIfNoHandDataAvailable;
}
FORCEINLINE void SetHiddenIfNoGloveDetected(const bool bInHiddenIfNoGloveDetected)
FORCEINLINE void SetHiddenIfNoHandDataAvailable(const bool bInHiddenIfNoHandDataAvailable)
{
bHiddenInGameIfNoGloveDetected = bInHiddenIfNoGloveDetected;
bHiddenInGameIfNoHandDataAvailable = bInHiddenIfNoHandDataAvailable;
}
FORCEINLINE void SetWristTracker(USGWristTrackerComponent* InWristTracker)
@@ -309,12 +336,17 @@ protected:
public:
bool IsGloveConnected() const;
USGHapticGlove* GetConnectedGlove() const;
USGHandPose* GetHandPose();
bool GetMotionControllerData(FXRMotionControllerData& OutMotionControllerData);
public:
const FName& GetFingerBoneName(int32 Finger, int32 Joint) const;
const FTransform& GetFingerBoneRefTransform(int32 Finger, int32 Joint) const;
const TArray<FName>& GetHandBoneNames() const;
const FName& GetHandBoneName(int32 Joint) const;
FRotator GetFingerBoneRefRotation(int32 Finger, int32 Joint) const;
TMap<FName, FRotator> GetFingersBonesRotations();
const FTransform& GetHandBoneRefTransform(const FName& BoneName) const;
const FTransform& GetHandBoneRefTransform(int32 Joint) const;
const FTransform& GetHandRootBoneRefTransform() const;
FRotator GetHandBoneRefRotation(const FName& BoneName) const;
FRotator GetHandBoneRefRotation(int32 Joint) const;
};
@@ -42,13 +42,9 @@
#include "Templates/UniquePtr.h"
#include "SGSettings/SGWristTrackingSettings.h"
#include "SGTypes/SGCoreTypes.h"
#include "SGWristTrackerComponent.generated.h"
class USGHandPose;
class USGHapticGlove;
UCLASS(Blueprintable, ClassGroup = MotionController, meta = (BlueprintSpawnableComponent))
class SENSEGLOVE_API USGWristTrackerComponent : public UMotionControllerComponent
{
@@ -41,7 +41,7 @@
#include "Math/Color.h"
#include "UObject/Object.h"
void FSGDebugGizmo::Draw(const UWorld* World, const FVector& Location, const FRotator& Rotation,
void FSGDebugGizmo::Draw(const UWorld* World, const FVector& Location, const FQuat& Rotation,
const FSGDebugGizmoSettings& Settings)
{
const float LifeTime = UGameplayStatics::GetWorldDeltaSeconds(World) * Settings.LifeTimeModifier;
@@ -43,78 +43,47 @@
#include "SGDebug/SGDebugGizmo.h"
void FSGDebugVirtualHand::Draw(const UWorld* World, const FVector& WristLocation, const FRotator& WristRotation,
const TArray<TArray<FVector>>& JointPositions,
const TArray<TArray<FRotator>>& JointRotations,
void FSGDebugVirtualHand::Draw(const UWorld* World,
const FXRMotionControllerData& MotionControllerData,
const FSGDebugVirtualHandSettings& Settings)
{
ensureAlwaysMsgf(Settings.DrawingMode != ESGDebugVirtualHandDrawingMode::None,
TEXT("Invalid virtual hand drawing mode!"));
ensureAlwaysMsgf(MotionControllerData.bValid,
TEXT("Invalid motion controller data!"));
ensureAlwaysMsgf(MotionControllerData.HandKeyPositions.Num() == MotionControllerData.HandKeyRotations.Num(),
TEXT("Mismatched motion controller data positions and rotations!"));
const float LifeTime = UGameplayStatics::GetWorldDeltaSeconds(World) * Settings.LifeTimeModifier;
if (Settings.DrawingMode == ESGDebugVirtualHandDrawingMode::CubicJoints)
for (TArray<FVector>::SizeType HandKeyIndex = 0;
HandKeyIndex < MotionControllerData.HandKeyPositions.Num(); ++HandKeyIndex)
{
DrawDebugBox(World, WristLocation, Settings.CubeExtent,
WristRotation.Quaternion(), Settings.CubeColor,
Settings.bPersistentLines, LifeTime, Settings.DepthPriority, Settings.CubeThickness);
}
else if (Settings.DrawingMode == ESGDebugVirtualHandDrawingMode::GizmoJoints)
{
FSGDebugGizmo::Draw(World,
WristLocation, WristRotation,
FSGDebugGizmoSettings{
Settings.GizmoLength,
Settings.GizmoThickness,
Settings.GizmoXAxisColor,
Settings.GizmoYAxisColor,
Settings.GizmoZAxisColor,
!!Settings.bPersistentLines,
Settings.LifeTimeModifier,
Settings.DepthPriority
});
}
const FVector& HandKeyPosition{MotionControllerData.HandKeyPositions[HandKeyIndex]};
const FQuat& HandKeyRotation{MotionControllerData.HandKeyRotations[HandKeyIndex]};
uint32 JointRotationsIndex = -1;
for (const TArray<FVector>& FingerJointPositions: JointPositions)
{
++JointRotationsIndex;
uint32 FingerJointRotationsIndex = -1;
const TArray<FRotator>& FingerJointRotations{JointRotations[JointRotationsIndex]};
for (const FVector& FingerJointPosition: FingerJointPositions)
if (Settings.DrawingMode == ESGDebugVirtualHandDrawingMode::CubicJoints)
{
++FingerJointRotationsIndex;
const FRotator& FingerJointRotation(FingerJointRotations[FingerJointRotationsIndex]);
const FVector DrawJointLocation(WristRotation.RotateVector(FingerJointPosition) + WristLocation);
const FQuat JointQuat{FingerJointRotation};
const FQuat WristQuat{WristRotation};
const FRotator DrawJointRotation{WristQuat * JointQuat};
if (Settings.DrawingMode == ESGDebugVirtualHandDrawingMode::CubicJoints)
{
DrawDebugBox(World, DrawJointLocation, Settings.CubeExtent,
DrawJointRotation.Quaternion(), Settings.CubeColor,
Settings.bPersistentLines, LifeTime, Settings.DepthPriority, Settings.CubeThickness);
}
else if (Settings.DrawingMode == ESGDebugVirtualHandDrawingMode::GizmoJoints)
{
FSGDebugGizmo::Draw(World,
DrawJointLocation, DrawJointRotation,
FSGDebugGizmoSettings{
Settings.GizmoLength,
Settings.GizmoThickness,
Settings.GizmoXAxisColor,
Settings.GizmoYAxisColor,
Settings.GizmoZAxisColor,
!!Settings.bPersistentLines,
Settings.LifeTimeModifier,
Settings.DepthPriority
});
}
DrawDebugBox(World, HandKeyPosition, Settings.CubeExtent,
HandKeyRotation, Settings.CubeColor,
Settings.bPersistentLines, LifeTime, Settings.DepthPriority, Settings.CubeThickness);
}
else if (Settings.DrawingMode == ESGDebugVirtualHandDrawingMode::GizmoJoints)
{
FSGDebugGizmo::Draw(World,
HandKeyPosition, HandKeyRotation,
FSGDebugGizmoSettings{
Settings.GizmoLength,
Settings.GizmoThickness,
Settings.GizmoXAxisColor,
Settings.GizmoYAxisColor,
Settings.GizmoZAxisColor,
!!Settings.bPersistentLines,
Settings.LifeTimeModifier,
Settings.DepthPriority
});
}
}
}
@@ -46,9 +46,17 @@ class SENSEGLOVEDEBUG_API FSGDebugGizmo final
public:
static void Draw(
const UWorld* World,
const FVector& Location, const FRotator& Rotation,
const FVector& Location, const FQuat& Rotation,
const FSGDebugGizmoSettings& Settings);
static FORCEINLINE void Draw(
const UWorld* World,
const FVector& Location, const FRotator& Rotation,
const FSGDebugGizmoSettings& Settings)
{
Draw(World, Location, Rotation.Quaternion(), Settings);
}
public:
FSGDebugGizmo() = delete;
virtual ~FSGDebugGizmo() = delete;
@@ -36,6 +36,7 @@
#pragma once
#include "Containers/Array.h"
#include "HeadMountedDisplayTypes.h"
#include "Math/Rotator.h"
#include "Math/Vector.h"
@@ -48,8 +49,7 @@ class SENSEGLOVEDEBUG_API FSGDebugVirtualHand final
public:
static void Draw(
const UWorld* World,
const FVector& WristLocation, const FRotator& WristRotation,
const TArray<TArray<FVector>>& JointPositions, const TArray<TArray<FRotator>>& JointRotations,
const FXRMotionControllerData& MotionControllerData,
const FSGDebugVirtualHandSettings& Settings);
public:
@@ -48,6 +48,7 @@ public class SenseGloveDebug : ModuleRules
"Core",
"CoreUObject",
"Engine",
"HeadMountedDisplay",
"SenseGloveLog",
"SenseGloveSettings",
"SenseGloveTypes",
@@ -36,30 +36,26 @@
#include "SGKismet/SGVirtualHandComponentKismetLibrary.h"
#include "SenseGlove/Components/SGVirtualHandComponent.h"
#include "SGCore/SGHandPose.h"
#include "SGCore/SGHapticGlove.h"
#include "SGUtils/SGArrayUtils.h"
TArray<FSGNameArray> UVirtualHandComponentKismetLibrary::GetLeftHandFingerBoneNames()
const TArray<FName>& UVirtualHandComponentKismetLibrary::GetLeftHandBoneNames()
{
return FSGArrayUtils::ToNestedBPArray<FName, FSGNameArray>(
USGVirtualHandComponent::GetLeftHandFingerBoneNames());
return USGVirtualHandComponent::GetLeftHandBoneNames();
}
TArray<FSGNameArray> UVirtualHandComponentKismetLibrary::GetRightHandFingerBoneNames()
const TArray<FName>& UVirtualHandComponentKismetLibrary::GetRightHandBoneNames()
{
return FSGArrayUtils::ToNestedBPArray<FName, FSGNameArray>(
USGVirtualHandComponent::GetRightHandFingerBoneNames());
return USGVirtualHandComponent::GetRightHandBoneNames();
}
const FName& UVirtualHandComponentKismetLibrary::GetLeftHandFingerBoneName(const int32 Finger, const int32 Joint)
const FName& UVirtualHandComponentKismetLibrary::GetLeftHandBoneName(const int32 Joint)
{
return USGVirtualHandComponent::GetLeftHandFingerBoneName(Finger, Joint);
return USGVirtualHandComponent::GetLeftHandBoneName(Joint);
}
const FName& UVirtualHandComponentKismetLibrary::GetRightHandFingerBoneName(const int32 Finger, const int32 Joint)
const FName& UVirtualHandComponentKismetLibrary::GetRightHandBoneName(const int32 Joint)
{
return USGVirtualHandComponent::GetRightHandFingerBoneName(Finger, Joint);
return USGVirtualHandComponent::GetRightHandBoneName(Joint);
}
bool UVirtualHandComponentKismetLibrary::IsLeft(const USGVirtualHandComponent* VirtualHandComponent)
@@ -78,16 +74,40 @@ void UVirtualHandComponentKismetLibrary::SetRight(
VirtualHandComponent->SetRight(bInRight);
}
bool UVirtualHandComponentKismetLibrary::IsHiddenInGameIfNoGloveDetected(
bool UVirtualHandComponentKismetLibrary::IsHiddenInGameIfNoHandDataAvailable(
const USGVirtualHandComponent* VirtualHandComponent)
{
return VirtualHandComponent->IsHiddenInGameIfNoGloveDetected();
return VirtualHandComponent->IsHiddenInGameIfNoHandDataAvailable();
}
void UVirtualHandComponentKismetLibrary::SetHiddenIfNoGloveDetected(
USGVirtualHandComponent* VirtualHandComponent, const bool bInHiddenIfNoGloveDetected)
void UVirtualHandComponentKismetLibrary::SetHiddenIfNoHandDataAvailable(
USGVirtualHandComponent* VirtualHandComponent, const bool bInHiddenIfNoHandDataAvailable)
{
VirtualHandComponent->SetHiddenIfNoGloveDetected(bInHiddenIfNoGloveDetected);
VirtualHandComponent->SetHiddenIfNoHandDataAvailable(bInHiddenIfNoHandDataAvailable);
}
const FRotator& UVirtualHandComponentKismetLibrary::GetAnimationBoneRotationCorrectionOffset(
const USGVirtualHandComponent* VirtualHandComponent)
{
return VirtualHandComponent->GetAnimationBoneRotationCorrectionOffset();
}
void UVirtualHandComponentKismetLibrary::SetAnimationBoneRotationCorrectionOffset(
USGVirtualHandComponent* VirtualHandComponent, const FRotator& InAnimationBoneRotationCorrectionOffset)
{
VirtualHandComponent->SetAnimationBoneRotationCorrectionOffset(InAnimationBoneRotationCorrectionOffset);
}
bool UVirtualHandComponentKismetLibrary::AnimationShouldApplyBoneLocation(
const USGVirtualHandComponent* VirtualHandComponent)
{
return VirtualHandComponent->AnimationShouldApplyBoneLocation();
}
void UVirtualHandComponentKismetLibrary::SetAnimationShouldApplyBoneLocation(
USGVirtualHandComponent* VirtualHandComponent, const bool bInAnimationShouldApplyBoneLocation)
{
VirtualHandComponent->SetAnimationShouldApplyBoneLocation(bInAnimationShouldApplyBoneLocation);
}
bool UVirtualHandComponentKismetLibrary::AutoStopsAllHapticsOnEndPlay(
@@ -240,31 +260,50 @@ USGHapticGlove* UVirtualHandComponentKismetLibrary::GetConnectedGlove(
return VirtualHandComponent->GetConnectedGlove();
}
USGHandPose* UVirtualHandComponentKismetLibrary::GetHandPose(USGVirtualHandComponent* VirtualHandComponent)
bool UVirtualHandComponentKismetLibrary::GetMotionControllerData(
USGVirtualHandComponent* VirtualHandComponent, FXRMotionControllerData& OutMotionControllerData)
{
return VirtualHandComponent->GetHandPose();
return VirtualHandComponent->GetMotionControllerData(OutMotionControllerData);
}
const FName& UVirtualHandComponentKismetLibrary::GetFingerBoneName(
const USGVirtualHandComponent* VirtualHandComponent, const int32 Finger, const int32 Joint)
const TArray<FName>& UVirtualHandComponentKismetLibrary::GetHandBoneNames(
const USGVirtualHandComponent* VirtualHandComponent)
{
return VirtualHandComponent->GetFingerBoneName(Finger, Joint);
return VirtualHandComponent->GetHandBoneNames();
}
const FTransform& UVirtualHandComponentKismetLibrary::GetFingerBoneRefTransform(
const USGVirtualHandComponent* VirtualHandComponent, const int32 Finger, const int32 Joint)
const FName& UVirtualHandComponentKismetLibrary::GetHandBoneName(
const USGVirtualHandComponent* VirtualHandComponent, const int32 Joint)
{
return VirtualHandComponent->GetFingerBoneRefTransform(Finger, Joint);
return VirtualHandComponent->GetHandBoneName(Joint);
}
FRotator UVirtualHandComponentKismetLibrary::GetFingerBoneRefRotation(
const USGVirtualHandComponent* VirtualHandComponent, const int32 Finger, const int32 Joint)
const FTransform& UVirtualHandComponentKismetLibrary::GetHandBoneRefTransform_BN(
const USGVirtualHandComponent* VirtualHandComponent, const FName& BoneName)
{
return VirtualHandComponent->GetFingerBoneRefRotation(Finger, Joint);
return VirtualHandComponent->GetHandBoneRefTransform(BoneName);
}
TMap<FName, FRotator> UVirtualHandComponentKismetLibrary::GetFingersBonesRotations(
USGVirtualHandComponent* VirtualHandComponent)
const FTransform& UVirtualHandComponentKismetLibrary::GetHandBoneRefTransform_J(
const USGVirtualHandComponent* VirtualHandComponent, const int32 Joint)
{
return VirtualHandComponent->GetFingersBonesRotations();
return VirtualHandComponent->GetHandBoneRefTransform(Joint);
}
const FTransform& UVirtualHandComponentKismetLibrary::GetHandRootBoneRefTransform(
const USGVirtualHandComponent* VirtualHandComponent)
{
return VirtualHandComponent->GetHandRootBoneRefTransform();
}
FRotator UVirtualHandComponentKismetLibrary::GetHandBoneRefRotation_BN(
const USGVirtualHandComponent* VirtualHandComponent, const FName& BoneName)
{
return VirtualHandComponent->GetHandBoneRefRotation(BoneName);
}
FRotator UVirtualHandComponentKismetLibrary::GetHandBoneRefRotation_J(
const USGVirtualHandComponent* VirtualHandComponent, const int32 Joint)
{
return VirtualHandComponent->GetHandBoneRefRotation(Joint);
}
@@ -37,13 +37,13 @@
#include "Containers/Array.h"
#include "Containers/Map.h"
#include "HeadMountedDisplayTypes.h"
#include "Math/Rotator.h"
#include "Math/Transform.h"
#include "UObject/NameTypes.h"
#include "SGKismet/SGBlueprintFunctionLibrary.h"
#include "SGSettings/SGDebugVirtualHandSettings.h"
#include "SGTypes/SGNameArray.h"
#include "SGVirtualHandComponentKismetLibrary.generated.h"
@@ -60,16 +60,16 @@ class SENSEGLOVEKISMET_API UVirtualHandComponentKismetLibrary final : public USG
public:
UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Virtual Hand Component")
static TArray<FSGNameArray> GetLeftHandFingerBoneNames();
static const TArray<FName>& GetLeftHandBoneNames();
UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Virtual Hand Component")
static TArray<FSGNameArray> GetRightHandFingerBoneNames();
static const TArray<FName>& GetRightHandBoneNames();
UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Virtual Hand Component")
static const FName& GetLeftHandFingerBoneName(int32 Finger, int32 Joint);
static const FName& GetLeftHandBoneName(int32 Joint);
UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Virtual Hand Component")
static const FName& GetRightHandFingerBoneName(int32 Finger, int32 Joint);
static const FName& GetRightHandBoneName(int32 Joint);
UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Virtual Hand Component")
static bool IsLeft(const USGVirtualHandComponent* VirtualHandComponent);
@@ -81,11 +81,29 @@ public:
static void SetRight(UPARAM(ref) USGVirtualHandComponent* VirtualHandComponent, bool bInRight);
UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Virtual Hand Component")
static bool IsHiddenInGameIfNoGloveDetected(const USGVirtualHandComponent* VirtualHandComponent);
static bool IsHiddenInGameIfNoHandDataAvailable(const USGVirtualHandComponent* VirtualHandComponent);
UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Virtual Hand Component")
static void SetHiddenIfNoGloveDetected(UPARAM(ref) USGVirtualHandComponent* VirtualHandComponent,
bool bInHiddenIfNoGloveDetected);
static void SetHiddenIfNoHandDataAvailable(UPARAM(ref) USGVirtualHandComponent* VirtualHandComponent,
bool bInHiddenIfNoHandDataAvailable);
UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Virtual Hand Component")
static const FRotator& GetAnimationBoneRotationCorrectionOffset(
const USGVirtualHandComponent* VirtualHandComponent);
UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Virtual Hand Component")
static void SetAnimationBoneRotationCorrectionOffset(
UPARAM(ref) USGVirtualHandComponent* VirtualHandComponent,
const FRotator& InAnimationBoneRotationCorrectionOffset);
UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Virtual Hand Component")
static bool AnimationShouldApplyBoneLocation(
const USGVirtualHandComponent* VirtualHandComponent);
UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Virtual Hand Component")
static void SetAnimationShouldApplyBoneLocation(
UPARAM(ref) USGVirtualHandComponent* VirtualHandComponent,
bool bInAnimationShouldApplyBoneLocation);
UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Virtual Hand Component")
static bool AutoStopsAllHapticsOnEndPlay(const USGVirtualHandComponent* VirtualHandComponent);
@@ -174,20 +192,36 @@ public:
static USGHapticGlove* GetConnectedGlove(const USGVirtualHandComponent* VirtualHandComponent);
UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Virtual Hand Component")
static USGHandPose* GetHandPose(UPARAM(ref) USGVirtualHandComponent* VirtualHandComponent);
static bool GetMotionControllerData(UPARAM(ref) USGVirtualHandComponent* VirtualHandComponent,
FXRMotionControllerData& OutMotionControllerData);
UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Virtual Hand Component")
static const FName& GetFingerBoneName(const USGVirtualHandComponent* VirtualHandComponent,
int32 Finger, int32 Joint);
static const TArray<FName>& GetHandBoneNames(const USGVirtualHandComponent* VirtualHandComponent);
UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Virtual Hand Component")
static const FTransform& GetFingerBoneRefTransform(const USGVirtualHandComponent* VirtualHandComponent,
int32 Finger, int32 Joint);
static const FName& GetHandBoneName(const USGVirtualHandComponent* VirtualHandComponent,
int32 Joint);
UFUNCTION(BlueprintPure, DisplayName="Get Hand Bone Ref Transform",
Category="SenseGlove | Components | Virtual Hand Component")
static const FTransform& GetHandBoneRefTransform_BN(const USGVirtualHandComponent* VirtualHandComponent,
const FName& BoneName);
UFUNCTION(BlueprintPure, DisplayName="Get Hand Bone Ref Transform",
Category="SenseGlove | Components | Virtual Hand Component")
static const FTransform& GetHandBoneRefTransform_J(const USGVirtualHandComponent* VirtualHandComponent,
int32 Joint);
UFUNCTION(BlueprintPure, Category="SenseGlove | Components | Virtual Hand Component")
static FRotator GetFingerBoneRefRotation(const USGVirtualHandComponent* VirtualHandComponent,
int32 Finger, int32 Joint);
static const FTransform& GetHandRootBoneRefTransform(const USGVirtualHandComponent* VirtualHandComponent);
UFUNCTION(BlueprintCallable, Category="SenseGlove | Components | Virtual Hand Component")
static TMap<FName, FRotator> GetFingersBonesRotations(UPARAM(ref) USGVirtualHandComponent* VirtualHandComponent);
UFUNCTION(BlueprintPure, DisplayName="Get Hand Bone Ref Rotation",
Category="SenseGlove | Components | Virtual Hand Component")
static FRotator GetHandBoneRefRotation_BN(const USGVirtualHandComponent* VirtualHandComponent,
const FName& BoneName);
UFUNCTION(BlueprintPure, DisplayName="Get Hand Bone Ref Rotation",
Category="SenseGlove | Components | Virtual Hand Component")
static FRotator GetHandBoneRefRotation_J(const USGVirtualHandComponent* VirtualHandComponent,
int32 Joint);
};
@@ -43,7 +43,6 @@
class USkeletalMeshComponent;
class USGWristTrackerComponent;
class USGHandPose;
UCLASS(meta=(ScriptName = "SesneGloveWristTrackerComponentKismetLibrary"))
class SENSEGLOVEKISMET_API UWristTrackerComponentKismetLibrary final : public USGBlueprintFunctionLibrary