refactor the animation, wrist tracking, and hand interaction manipulation systems for FXRMotionControllerData compatibility
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user