97 lines
2.8 KiB
C++
97 lines
2.8 KiB
C++
// 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);
|
|
}
|
|
}
|