October3d55/M/PICOXRPlugin/Source/PICOXRInput/Private/PXR_HandComponent.cpp

139 lines
3.9 KiB
C++

// Copyright PICO Technology Co., Ltd. All rights reserved.
// This plugin incorporates portions of the Unreal® Engine. Unreal® is a trademark or registered trademark of Epic Games, Inc. in the United States of America and elsewhere.
// Copyright Epic Games, Inc. All Rights Reserved.
#include "PXR_HandComponent.h"
#include <GameFramework/PlayerController.h>
#include "PXR_HMDRuntimeSettings.h"
#include "PXR_EventManager.h"
#include "PXR_InputFunctionLibrary.h"
#include "PXR_InputState.h"
#include "Engine/SkeletalMesh.h"
#include "Components/InputComponent.h"
#include "Materials/MaterialInterface.h"
#include "PXR_HMDFunctionLibrary.h"
#include "Camera/PlayerCameraManager.h"
#include "PXR_Input.h"
#include "PXR_Log.h"
UPICOXRHandComponent::UPICOXRHandComponent(const FObjectInitializer& ObjectInitializer) :
Super(ObjectInitializer),
SkeletonType(EPICOXRHandType::None),
bUpdateHandScale(false)
{
PrimaryComponentTick.bCanEverTick = true;
PrimaryComponentTick.bStartWithTickEnabled = true;
PrimaryComponentTick.TickGroup = TG_PrePhysics;
bAutoActivate = true;
bWantsInitializeComponent = true;
for (uint8 BoneIndex = 0; BoneIndex < static_cast<uint8>(EHandJointCount); BoneIndex++)
{
BoneNameMappings.Add(static_cast<EPICOXRHandJoint>(BoneIndex), TEXT(""));
}
}
void UPICOXRHandComponent::BeginPlay()
{
Super::BeginPlay();
// Use custom mesh if a skeletal mesh is already set, else try to load the runtime mesh
if (GetSkinnedAsset())
{
bCustomHandMesh = true;
}
//Hide Component if HandTracking is Disabled
const bool bStartHidden = UPICOXRInputFunctionLibrary::IsHandTrackingEnabled() ? false : true;
SetHiddenInGame(bStartHidden, true);
UPICOXRSettings* HMDSettings = GetMutableDefault<UPICOXRSettings>();
if (HMDSettings)
{
bUpdateHandScale=HMDSettings->bAdaptiveHandModel;
}
}
void UPICOXRHandComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
if (IsInGameThread())
{
const AActor* Owner = GetOwner();
bHasAuthority = Owner->HasLocalNetOwner();
}
if (bHasAuthority)
{
bool bHidden = false;
if (UPICOXRInputFunctionLibrary::IsHandTrackingEnabled())
{
if (bHideByConfidence)
{
const EPICOXRHandTrackingConfidence TrackingConfidence = UPICOXRInputFunctionLibrary::GetTrackingConfidence(SkeletonType);
bHidden |= TrackingConfidence != EPICOXRHandTrackingConfidence::High;
}
if (bUpdateHandScale)
{
const float NewScale = UPICOXRInputFunctionLibrary::GetHandScale(SkeletonType);
SetRelativeScale3D(FVector(NewScale));
}
if (GetSkinnedAsset())
{
UpdateBonePose();
UpdateHandTransform();
}
}
else
{
bHidden = true;
}
if (bHidden != bHiddenInGame)
{
SetHiddenInGame(bHidden, true);
}
}
}
void UPICOXRHandComponent::UpdateBonePose()
{
if (bCustomHandMesh)
{
for (auto& BoneElem : BoneNameMappings)
{
const int32 BoneIndex = GetSkinnedAsset()->GetRefSkeleton().FindBoneIndex(BoneElem.Value);
if (BoneIndex >= 0)
{
FQuat BoneRotation = UPICOXRInputFunctionLibrary::GetBoneRotation(SkeletonType, BoneElem.Key);
if (!BoneRotation.IsIdentity()&&BoneRotation.IsNormalized())
{
SetBoneRotationByName(BoneElem.Value, BoneRotation.Rotator(), EBoneSpaces::ComponentSpace);
}
const FVector BoneLocation = UPICOXRInputFunctionLibrary::GetBoneLocation(SkeletonType, BoneElem.Key);
if (!BoneLocation.IsZero()&&!BoneLocation.ContainsNaN()&&bApplyLocationToBones)
{
SetBoneLocationByName(BoneElem.Value, BoneLocation, EBoneSpaces::WorldSpace);
}
}
}
}
MarkRefreshTransformDirty();
}
void UPICOXRHandComponent::UpdateHandTransform()
{
const FTransform HandPose = UPICOXRInputFunctionLibrary::GetHandRootPose(SkeletonType);
if (HandPose.IsValid() && !HandPose.Equals(FTransform()))
{
if (!HandPose.GetLocation().ContainsNaN())
{
this->SetRelativeLocation(HandPose.GetLocation());
}
}
}