October3d55/M/PICOOpen7991a2a23d57V5/Source/PICOOpenXRHandTracking/Private/PICO_HandTrackingComponent.cpp

97 lines
2.8 KiB
C++
Raw Normal View History

2025-03-10 09:43:27 +08:00
// Copyright 2023 PICO Inc. All Rights Reserved.
#include "PICO_HandTrackingComponent.h"
#include "HeadMountedDisplayFunctionLibrary.h"
#include "Engine/SkeletalMesh.h"
#include "PICO_HandTrackingFunctionLibrary.h"
UHandTrackingComponentPICO::UHandTrackingComponentPICO(const FObjectInitializer& ObjectInitializer)
:Super(ObjectInitializer)
, SkeletonMeshType(EHandTypePICO::HandLeft)
, ApplyLocationToEveryBone(false)
, AutoHide(false)
, bHandTrackingAvailable(false)
{
PrimaryComponentTick.bCanEverTick = true;
PrimaryComponentTick.bStartWithTickEnabled = true;
PrimaryComponentTick.TickGroup = TG_PrePhysics;
for (int KeypointIndex = 0; KeypointIndex < EHandKeypointCount; KeypointIndex++)
{
BoneMappings.Add(EHandKeypoint(KeypointIndex), TEXT(""));
}
}
void UHandTrackingComponentPICO::BeginPlay()
{
Super::BeginPlay();
FXRMotionControllerData Data;
UHeadMountedDisplayFunctionLibrary::GetMotionControllerData(nullptr, EControllerHand(SkeletonMeshType), Data);
if (Data.DeviceVisualType == EXRVisualType::Hand)
{
bHandTrackingAvailable = true;
}
if (AutoHide)
{
SetHiddenInGame(true, true);
}
}
void UHandTrackingComponentPICO::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
bool bHidden = true;
if (bHandTrackingAvailable && GetSkinnedAsset())
{
FXRMotionControllerData Data;
UHeadMountedDisplayFunctionLibrary::GetMotionControllerData(nullptr, EControllerHand(SkeletonMeshType), Data);
if (Data.bValid)
{
bHidden = false;
for (auto& BoneMapping : BoneMappings)
{
const auto& HandKeypoint = BoneMapping.Key;
const auto& BoneName = BoneMapping.Value;
int32 BoneIndex = GetSkinnedAsset()->GetRefSkeleton().FindBoneIndex(BoneName);
if (BoneIndex >= 0)
{
if(Data.HandKeyPositions.IsValidIndex((uint8)HandKeypoint))
{
const FQuat& WorldRotation = Data.HandKeyRotations[(uint8)HandKeypoint];
const FVector& WorldLocation = Data.HandKeyPositions[(uint8)HandKeypoint];
SetBoneRotationByName(BoneName, WorldRotation.Rotator(), EBoneSpaces::WorldSpace);
if(HandKeypoint == EHandKeypoint::Wrist || ApplyLocationToEveryBone)
{
SetBoneLocationByName(BoneName, WorldLocation, EBoneSpaces::WorldSpace);
}
if(HandKeypoint == EHandKeypoint::Wrist)
{
this->SetWorldLocation(WorldLocation);
this->SetWorldRotation(WorldRotation);
}
if (AutoScaleComponent)
{
float Scale = 1.0f;
UHandTrackingFunctionLibraryPICO::GetHandTrackingMeshScalePICO(EControllerHand(SkeletonMeshType), Scale);
this->SetRelativeScale3D(FVector(Scale));
}
}
}
}
}
else
{
bHidden = true;
}
}
if (AutoHide && bHidden != bHiddenInGame)
{
SetHiddenInGame(bHidden, true);
}
}