VRTowerDef/Plugins/MetaXR/Source/OculusXRHMD/Private/OculusXRFunctionLibrary.cpp

986 lines
31 KiB
C++

// @lint-ignore-every LICENSELINT
// Copyright Epic Games, Inc. All Rights Reserved.
#include "OculusXRFunctionLibrary.h"
#include "OculusXRHMDPrivate.h"
#include "OculusXRHMD.h"
#include "Logging/MessageLog.h"
#define LOCTEXT_NAMESPACE "OculusFunctionLibrary"
//-------------------------------------------------------------------------------------------------
// UOculusXRFunctionLibrary
//-------------------------------------------------------------------------------------------------
UOculusXRFunctionLibrary::UOculusXRFunctionLibrary(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
}
OculusXRHMD::FOculusXRHMD* UOculusXRFunctionLibrary::GetOculusXRHMD()
{
return OculusXRHMD::FOculusXRHMD::GetOculusXRHMD();
}
void UOculusXRFunctionLibrary::GetPose(FRotator& DeviceRotation, FVector& DevicePosition, FVector& NeckPosition, bool bUseOrienationForPlayerCamera, bool bUsePositionForPlayerCamera, const FVector PositionScale)
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD && OculusXRHMD->IsHeadTrackingAllowed())
{
FQuat HeadOrientation = FQuat::Identity;
FVector HeadPosition = FVector::ZeroVector;
OculusXRHMD->GetCurrentPose(OculusXRHMD->HMDDeviceId, HeadOrientation, HeadPosition);
DeviceRotation = HeadOrientation.Rotator();
DevicePosition = HeadPosition;
NeckPosition = OculusXRHMD->GetNeckPosition(HeadOrientation, HeadPosition);
}
else
#endif // #if OCULUS_HMD_SUPPORTED_PLATFORMS
{
DeviceRotation = FRotator::ZeroRotator;
DevicePosition = FVector::ZeroVector;
NeckPosition = FVector::ZeroVector;
}
}
void UOculusXRFunctionLibrary::SetBaseRotationAndBaseOffsetInMeters(FRotator Rotation, FVector BaseOffsetInMeters, EOrientPositionSelector::Type Options)
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
if ((Options == EOrientPositionSelector::Orientation) || (Options == EOrientPositionSelector::OrientationAndPosition))
{
OculusXRHMD->SetBaseRotation(Rotation);
}
if ((Options == EOrientPositionSelector::Position) || (Options == EOrientPositionSelector::OrientationAndPosition))
{
OculusXRHMD->SetBaseOffsetInMeters(BaseOffsetInMeters);
}
}
#endif // OCULUS_HMD_SUPPORTED_PLATFORMS
}
void UOculusXRFunctionLibrary::GetBaseRotationAndBaseOffsetInMeters(FRotator& OutRotation, FVector& OutBaseOffsetInMeters)
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
OutRotation = OculusXRHMD->GetBaseRotation();
OutBaseOffsetInMeters = OculusXRHMD->GetBaseOffsetInMeters();
}
else
{
OutRotation = FRotator::ZeroRotator;
OutBaseOffsetInMeters = FVector::ZeroVector;
}
#endif // OCULUS_HMD_SUPPORTED_PLATFORMS
}
void UOculusXRFunctionLibrary::GetRawSensorData(FVector& AngularAcceleration, FVector& LinearAcceleration, FVector& AngularVelocity, FVector& LinearVelocity, float& TimeInSeconds, EOculusXRTrackedDeviceType DeviceType)
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr && OculusXRHMD->IsHMDActive())
{
ovrpPoseStatef state;
if (OVRP_SUCCESS(FOculusXRHMDModule::GetPluginWrapper().GetNodePoseState3(ovrpStep_Render, OVRP_CURRENT_FRAMEINDEX, OculusXRHMD::ToOvrpNode(DeviceType), &state)))
{
AngularAcceleration = OculusXRHMD::ToFVector(state.AngularAcceleration);
LinearAcceleration = OculusXRHMD::ToFVector(state.Acceleration);
AngularVelocity = OculusXRHMD::ToFVector(state.AngularVelocity);
LinearVelocity = OculusXRHMD::ToFVector(state.Velocity);
TimeInSeconds = state.Time;
}
}
#endif // OCULUS_HMD_SUPPORTED_PLATFORMS
}
bool UOculusXRFunctionLibrary::IsDeviceTracked(EOculusXRTrackedDeviceType DeviceType)
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr && OculusXRHMD->IsHMDActive())
{
ovrpBool Present;
if (OVRP_SUCCESS(FOculusXRHMDModule::GetPluginWrapper().GetNodePresent2(OculusXRHMD::ToOvrpNode(DeviceType), &Present)))
{
return Present != ovrpBool_False;
}
else
{
return false;
}
}
#endif // OCULUS_HMD_SUPPORTED_PLATFORMS
return false;
}
void UOculusXRFunctionLibrary::GetSuggestedCpuAndGpuPerformanceLevels(EOculusXRProcessorPerformanceLevel& CpuPerfLevel, EOculusXRProcessorPerformanceLevel& GpuPerfLevel)
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr && OculusXRHMD->IsHMDActive())
{
OculusXRHMD->GetSuggestedCpuAndGpuPerformanceLevels(CpuPerfLevel, GpuPerfLevel);
}
#endif // OCULUS_HMD_SUPPORTED_PLATFORMS
}
void UOculusXRFunctionLibrary::SetSuggestedCpuAndGpuPerformanceLevels(EOculusXRProcessorPerformanceLevel CpuPerfLevel, EOculusXRProcessorPerformanceLevel GpuPerfLevel)
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr && OculusXRHMD->IsHMDActive())
{
OculusXRHMD->SetSuggestedCpuAndGpuPerformanceLevels(CpuPerfLevel, GpuPerfLevel);
}
#endif // OCULUS_HMD_SUPPORTED_PLATFORMS
}
void UOculusXRFunctionLibrary::SetCPUAndGPULevels(int CPULevel, int GPULevel)
{
// Deprecated. Please use Get/SetSuggestedCpuAndGpuPerformanceLevels instead.
}
bool UOculusXRFunctionLibrary::GetUserProfile(FOculusXRHmdUserProfile& Profile)
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
OculusXRHMD::FOculusXRHMD::UserProfile Data;
if (OculusXRHMD->GetUserProfile(Data))
{
Profile.Name = "";
Profile.Gender = "Unknown";
Profile.PlayerHeight = 0.0f;
Profile.EyeHeight = Data.EyeHeight;
Profile.IPD = Data.IPD;
Profile.NeckToEyeDistance = FVector2D(Data.EyeDepth, 0.0f);
return true;
}
}
#endif // OCULUS_HMD_SUPPORTED_PLATFORMS
return false;
}
void UOculusXRFunctionLibrary::SetBaseRotationAndPositionOffset(FRotator BaseRot, FVector PosOffset, EOrientPositionSelector::Type Options)
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
if (Options == EOrientPositionSelector::Orientation || Options == EOrientPositionSelector::OrientationAndPosition)
{
OculusXRHMD->SetBaseRotation(BaseRot);
}
}
#endif // OCULUS_HMD_SUPPORTED_PLATFORMS
}
void UOculusXRFunctionLibrary::GetBaseRotationAndPositionOffset(FRotator& OutRot, FVector& OutPosOffset)
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
OutRot = OculusXRHMD->GetBaseRotation();
OutPosOffset = FVector::ZeroVector;
}
#endif // OCULUS_HMD_SUPPORTED_PLATFORMS
}
void UOculusXRFunctionLibrary::AddLoadingSplashScreen(class UTexture2D* Texture, FVector TranslationInMeters, FRotator Rotation, FVector2D SizeInMeters, FRotator DeltaRotation, bool bClearBeforeAdd)
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
OculusXRHMD::FSplash* Splash = OculusXRHMD->GetSplash();
if (Splash)
{
if (bClearBeforeAdd)
{
Splash->ClearSplashes();
}
FOculusXRSplashDesc Desc;
Desc.LoadingTexture = Texture;
Desc.QuadSizeInMeters = SizeInMeters;
Desc.TransformInMeters = FTransform(Rotation, TranslationInMeters);
Desc.DeltaRotation = FQuat(DeltaRotation);
Splash->AddSplash(Desc);
}
}
#endif // OCULUS_HMD_SUPPORTED_PLATFORMS
}
void UOculusXRFunctionLibrary::ClearLoadingSplashScreens()
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
OculusXRHMD::FSplash* Splash = OculusXRHMD->GetSplash();
if (Splash)
{
Splash->ClearSplashes();
}
}
#endif // OCULUS_HMD_SUPPORTED_PLATFORMS
}
bool UOculusXRFunctionLibrary::HasInputFocus()
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
const OculusXRHMD::FOculusXRHMD* const OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr && OculusXRHMD->IsHMDActive())
{
ovrpBool HasFocus;
if (OVRP_SUCCESS(FOculusXRHMDModule::GetPluginWrapper().GetAppHasInputFocus(&HasFocus)))
{
return HasFocus != ovrpBool_False;
}
}
#endif // OCULUS_HMD_SUPPORTED_PLATFORMS
return false;
}
bool UOculusXRFunctionLibrary::HasSystemOverlayPresent()
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
const OculusXRHMD::FOculusXRHMD* const OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr && OculusXRHMD->IsHMDActive())
{
ovrpBool HasFocus;
if (OVRP_SUCCESS(FOculusXRHMDModule::GetPluginWrapper().GetAppHasInputFocus(&HasFocus)))
{
return HasFocus == ovrpBool_False;
}
}
#endif // OCULUS_HMD_SUPPORTED_PLATFORMS
return false;
}
void UOculusXRFunctionLibrary::GetGPUUtilization(bool& IsGPUAvailable, float& GPUUtilization)
{
GPUUtilization = 0.0f;
#if OCULUS_HMD_SUPPORTED_PLATFORMS
const OculusXRHMD::FOculusXRHMD* const OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
ovrpBool bIsSupported = ovrpBool_False;
if (OVRP_SUCCESS(FOculusXRHMDModule::GetPluginWrapper().IsPerfMetricsSupported(ovrpPerfMetrics_System_GpuUtilPercentage_Float, &bIsSupported)) && bIsSupported == ovrpBool_True)
{
if (OVRP_SUCCESS(FOculusXRHMDModule::GetPluginWrapper().GetPerfMetricsFloat(ovrpPerfMetrics_System_GpuUtilPercentage_Float, &GPUUtilization)))
{
IsGPUAvailable = true;
GPUUtilization *= 100;
}
}
}
#endif // OCULUS_HMD_SUPPORTED_PLATFORMS
}
float UOculusXRFunctionLibrary::GetGPUFrameTime()
{
float FrameTime = 0;
#if OCULUS_HMD_SUPPORTED_PLATFORMS
const OculusXRHMD::FOculusXRHMD* const OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
ovrpBool bIsSupported = ovrpBool_False;
if (OVRP_SUCCESS(FOculusXRHMDModule::GetPluginWrapper().IsPerfMetricsSupported(ovrpPerfMetrics_App_GpuTime_Float, &bIsSupported)) && bIsSupported == ovrpBool_True)
{
if (OVRP_SUCCESS(FOculusXRHMDModule::GetPluginWrapper().GetPerfMetricsFloat(ovrpPerfMetrics_App_GpuTime_Float, &FrameTime)))
{
return FrameTime * 1000;
}
}
}
#endif // OCULUS_HMD_SUPPORTED_PLATFORMS
return 0.0f;
}
EOculusXRFoveatedRenderingMethod UOculusXRFunctionLibrary::GetFoveatedRenderingMethod()
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
ovrpBool enabled;
if (OVRP_SUCCESS(FOculusXRHMDModule::GetPluginWrapper().GetFoveationEyeTracked(&enabled)))
{
return enabled == ovrpBool_True ? EOculusXRFoveatedRenderingMethod::EyeTrackedFoveatedRendering : EOculusXRFoveatedRenderingMethod::FixedFoveatedRendering;
}
}
#endif // OCULUS_HMD_SUPPORTED_PLATFORMS
return EOculusXRFoveatedRenderingMethod::FixedFoveatedRendering;
}
void UOculusXRFunctionLibrary::SetFoveatedRenderingMethod(EOculusXRFoveatedRenderingMethod Method)
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
OculusXRHMD->SetFoveatedRenderingMethod(Method);
}
#endif // OCULUS_HMD_SUPPORTED_PLATFORMS
}
void UOculusXRFunctionLibrary::SetFoveatedRenderingLevel(EOculusXRFoveatedRenderingLevel level, bool isDynamic)
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
OculusXRHMD->SetFoveatedRenderingLevel(level, isDynamic);
}
#endif // OCULUS_HMD_SUPPORTED_PLATFORMS
}
EOculusXRFoveatedRenderingLevel UOculusXRFunctionLibrary::GetFoveatedRenderingLevel()
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
ovrpTiledMultiResLevel Lvl;
if (OVRP_SUCCESS(FOculusXRHMDModule::GetPluginWrapper().GetTiledMultiResLevel(&Lvl)))
{
return (EOculusXRFoveatedRenderingLevel)Lvl;
}
}
#endif // OCULUS_HMD_SUPPORTED_PLATFORMS
return EOculusXRFoveatedRenderingLevel::Off;
}
bool UOculusXRFunctionLibrary::GetEyeTrackedFoveatedRenderingSupported()
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
// Always return false on other engine releases, since they don't have FDM offset support
#ifdef WITH_OCULUS_BRANCH
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
ovrpBool Supported;
if (OVRP_SUCCESS(FOculusXRHMDModule::GetPluginWrapper().GetFoveationEyeTrackedSupported(&Supported)))
{
return Supported == ovrpBool_True;
}
}
#endif // WITH_OCULUS_BRANCH
#endif // OCULUS_HMD_SUPPORTED_PLATFORMS
return false;
}
FString UOculusXRFunctionLibrary::GetDeviceName()
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
const char* NameString;
if (OVRP_SUCCESS(FOculusXRHMDModule::GetPluginWrapper().GetSystemProductName2(&NameString)) && NameString)
{
return FString(NameString);
}
}
#endif
return FString();
}
EOculusXRDeviceType UOculusXRFunctionLibrary::GetDeviceType()
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
if (OculusXRHMD->GetSettings())
{
switch (OculusXRHMD->GetSettings()->SystemHeadset)
{
case ovrpSystemHeadset_Oculus_Quest:
return EOculusXRDeviceType::OculusQuest_Deprecated;
case ovrpSystemHeadset_Oculus_Quest_2:
return EOculusXRDeviceType::OculusQuest2;
case ovrpSystemHeadset_Meta_Quest_Pro:
return EOculusXRDeviceType::MetaQuestPro;
case ovrpSystemHeadset_Meta_Quest_3:
return EOculusXRDeviceType::MetaQuest3;
case ovrpSystemHeadset_Rift_CV1:
return EOculusXRDeviceType::Rift;
case ovrpSystemHeadset_Rift_S:
return EOculusXRDeviceType::Rift_S;
case ovrpSystemHeadset_Oculus_Link_Quest:
return EOculusXRDeviceType::Quest_Link_Deprecated;
case ovrpSystemHeadset_Oculus_Link_Quest_2:
return EOculusXRDeviceType::Quest2_Link;
case ovrpSystemHeadset_Meta_Link_Quest_Pro:
return EOculusXRDeviceType::MetaQuestProLink;
case ovrpSystemHeadset_Meta_Link_Quest_3:
return EOculusXRDeviceType::MetaQuest3Link;
default:
break;
}
}
}
#endif
return EOculusXRDeviceType::OculusUnknown;
}
EOculusXRControllerType UOculusXRFunctionLibrary::GetControllerType(EControllerHand deviceHand)
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
auto getOVRPHand = [](EControllerHand hand) {
switch (hand)
{
case EControllerHand::Left:
return ovrpHand::ovrpHand_Left;
case EControllerHand::Right:
return ovrpHand::ovrpHand_Right;
default:
return ovrpHand::ovrpHand_None;
}
return ovrpHand::ovrpHand_None;
};
auto getEControllerType = [](ovrpInteractionProfile profile) {
switch (profile)
{
case ovrpInteractionProfile::ovrpInteractionProfile_Touch:
return EOculusXRControllerType::MetaQuestTouch;
case ovrpInteractionProfile::ovrpInteractionProfile_TouchPro:
return EOculusXRControllerType::MetaQuestTouchPro;
case ovrpInteractionProfile::ovrpInteractionProfile_TouchPlus:
return EOculusXRControllerType::MetaQuestTouchPlus;
default:
return EOculusXRControllerType::None;
}
return EOculusXRControllerType::None;
};
ovrpInteractionProfile interactionProfile = ovrpInteractionProfile::ovrpInteractionProfile_None;
ovrpHand hand = getOVRPHand(deviceHand);
if (hand == ovrpHand::ovrpHand_None)
return EOculusXRControllerType::Unknown;
if (OVRP_SUCCESS(FOculusXRHMDModule::GetPluginWrapper().GetCurrentInteractionProfile(hand, &interactionProfile)))
{
return getEControllerType(interactionProfile);
}
return EOculusXRControllerType::Unknown;
#endif
return EOculusXRControllerType::Unknown;
}
TArray<float> UOculusXRFunctionLibrary::GetAvailableDisplayFrequencies()
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
int NumberOfFrequencies;
if (OVRP_SUCCESS(FOculusXRHMDModule::GetPluginWrapper().GetSystemDisplayAvailableFrequencies(nullptr, &NumberOfFrequencies)))
{
TArray<float> freqArray;
freqArray.SetNum(NumberOfFrequencies);
FOculusXRHMDModule::GetPluginWrapper().GetSystemDisplayAvailableFrequencies(freqArray.GetData(), &NumberOfFrequencies);
return freqArray;
}
}
#endif
return TArray<float>();
}
float UOculusXRFunctionLibrary::GetCurrentDisplayFrequency()
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
float Frequency;
if (OVRP_SUCCESS(FOculusXRHMDModule::GetPluginWrapper().GetSystemDisplayFrequency2(&Frequency)))
{
return Frequency;
}
}
#endif
return 0.0f;
}
void UOculusXRFunctionLibrary::SetDisplayFrequency(float RequestedFrequency)
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
FOculusXRHMDModule::GetPluginWrapper().SetSystemDisplayFrequency(RequestedFrequency);
}
#endif
}
void UOculusXRFunctionLibrary::EnablePositionTracking(bool bPositionTracking)
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
FOculusXRHMDModule::GetPluginWrapper().SetTrackingPositionEnabled2(bPositionTracking);
}
#endif
}
void UOculusXRFunctionLibrary::EnableOrientationTracking(bool bOrientationTracking)
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
FOculusXRHMDModule::GetPluginWrapper().SetTrackingOrientationEnabled2(bOrientationTracking);
}
#endif
}
void UOculusXRFunctionLibrary::SetColorScaleAndOffset(FLinearColor ColorScale, FLinearColor ColorOffset, bool bApplyToAllLayers)
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
OculusXRHMD->SetColorScaleAndOffset(ColorScale, ColorOffset, bApplyToAllLayers);
}
#endif
}
class IStereoLayers* UOculusXRFunctionLibrary::GetStereoLayers()
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
return OculusXRHMD;
}
#endif // OCULUS_HMD_SUPPORTED_PLATFORMS
return nullptr;
}
/** Helper that converts EOculusXRBoundaryType to ovrpBoundaryType */
#if OCULUS_HMD_SUPPORTED_PLATFORMS
static ovrpBoundaryType ToOvrpBoundaryType(EOculusXRBoundaryType Source)
{
switch (Source)
{
case EOculusXRBoundaryType::Boundary_PlayArea:
return ovrpBoundary_PlayArea;
case EOculusXRBoundaryType::Boundary_Outer:
default:
return ovrpBoundary_Outer;
}
}
#endif // OCULUS_HMD_SUPPORTED_PLATFORMS
bool UOculusXRFunctionLibrary::IsGuardianConfigured()
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
ovrpBool boundaryConfigured;
return OVRP_SUCCESS(FOculusXRHMDModule::GetPluginWrapper().GetBoundaryConfigured2(&boundaryConfigured)) && boundaryConfigured;
}
#endif
return false;
}
bool UOculusXRFunctionLibrary::IsGuardianDisplayed()
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
ovrpBool boundaryVisible;
return OVRP_SUCCESS(FOculusXRHMDModule::GetPluginWrapper().GetBoundaryVisible2(&boundaryVisible)) && boundaryVisible;
}
#endif
return false;
}
TArray<FVector> UOculusXRFunctionLibrary::GetGuardianPoints(EOculusXRBoundaryType BoundaryType, bool UsePawnSpace /* = false */)
{
TArray<FVector> BoundaryPointList;
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
ovrpBool bBoundaryConfigured = false;
if (OVRP_SUCCESS(FOculusXRHMDModule::GetPluginWrapper().GetBoundaryConfigured2(&bBoundaryConfigured)) && bBoundaryConfigured)
{
ovrpBoundaryType obt = ToOvrpBoundaryType(BoundaryType);
int NumPoints = 0;
if (OVRP_SUCCESS(FOculusXRHMDModule::GetPluginWrapper().GetBoundaryGeometry3(obt, nullptr, &NumPoints)))
{
//allocate points
const int BufferSize = NumPoints;
ovrpVector3f* BoundaryPoints = new ovrpVector3f[BufferSize];
if (OVRP_SUCCESS(FOculusXRHMDModule::GetPluginWrapper().GetBoundaryGeometry3(obt, BoundaryPoints, &NumPoints)))
{
NumPoints = FMath::Min(BufferSize, NumPoints);
check(NumPoints <= BufferSize); // For static analyzer
BoundaryPointList.Reserve(NumPoints);
for (int i = 0; i < NumPoints; i++)
{
FVector point;
if (UsePawnSpace)
{
point = OculusXRHMD->ConvertVector_M2U(BoundaryPoints[i]);
}
else
{
point = OculusXRHMD->ScaleAndMovePointWithPlayer(BoundaryPoints[i]);
}
BoundaryPointList.Add(point);
}
}
delete[] BoundaryPoints;
}
}
}
#endif
return BoundaryPointList;
}
FVector UOculusXRFunctionLibrary::GetGuardianDimensions(EOculusXRBoundaryType BoundaryType)
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
ovrpBoundaryType obt = ToOvrpBoundaryType(BoundaryType);
ovrpVector3f Dimensions;
if (OVRP_FAILURE(FOculusXRHMDModule::GetPluginWrapper().GetBoundaryDimensions2(obt, &Dimensions)))
return FVector::ZeroVector;
Dimensions.z *= -1.0;
return OculusXRHMD->ConvertVector_M2U(Dimensions);
}
#endif
return FVector::ZeroVector;
}
FTransform UOculusXRFunctionLibrary::GetPlayAreaTransform()
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
ovrpBool bBoundaryConfigured = false;
if (OVRP_SUCCESS(FOculusXRHMDModule::GetPluginWrapper().GetBoundaryConfigured2(&bBoundaryConfigured)) && bBoundaryConfigured)
{
int NumPoints = 4;
ovrpVector3f BoundaryPoints[4];
if (OVRP_SUCCESS(FOculusXRHMDModule::GetPluginWrapper().GetBoundaryGeometry3(ovrpBoundary_PlayArea, BoundaryPoints, &NumPoints)))
{
FVector ConvertedPoints[4];
for (int i = 0; i < NumPoints; i++)
{
ConvertedPoints[i] = OculusXRHMD->ScaleAndMovePointWithPlayer(BoundaryPoints[i]);
}
float metersScale = OculusXRHMD->GetWorldToMetersScale();
FVector Edge = ConvertedPoints[1] - ConvertedPoints[0];
float Angle = FMath::Acos((Edge).GetSafeNormal() | FVector::RightVector);
FQuat Rotation(FVector::UpVector, Edge.X < 0 ? Angle : -Angle);
FVector Position = (ConvertedPoints[0] + ConvertedPoints[1] + ConvertedPoints[2] + ConvertedPoints[3]) / 4;
FVector Scale(FVector::Distance(ConvertedPoints[3], ConvertedPoints[0]) / metersScale, FVector::Distance(ConvertedPoints[1], ConvertedPoints[0]) / metersScale, 1.0);
return FTransform(Rotation, Position, Scale);
}
}
}
#endif
return FTransform();
}
FOculusXRGuardianTestResult UOculusXRFunctionLibrary::GetPointGuardianIntersection(const FVector Point, EOculusXRBoundaryType BoundaryType)
{
FOculusXRGuardianTestResult InteractionInfo;
memset(&InteractionInfo, 0, sizeof(FOculusXRGuardianTestResult));
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
ovrpVector3f OvrpPoint = OculusXRHMD->WorldLocationToOculusPoint(Point);
ovrpBoundaryType OvrpBoundaryType = ToOvrpBoundaryType(BoundaryType);
ovrpBoundaryTestResult InteractionResult;
if (OVRP_SUCCESS(FOculusXRHMDModule::GetPluginWrapper().TestBoundaryPoint2(OvrpPoint, OvrpBoundaryType, &InteractionResult)))
{
InteractionInfo.IsTriggering = (InteractionResult.IsTriggering != 0);
InteractionInfo.ClosestDistance = OculusXRHMD->ConvertFloat_M2U(InteractionResult.ClosestDistance);
InteractionInfo.ClosestPoint = OculusXRHMD->ScaleAndMovePointWithPlayer(InteractionResult.ClosestPoint);
InteractionInfo.ClosestPointNormal = OculusXRHMD->ConvertVector_M2U(InteractionResult.ClosestPointNormal);
InteractionInfo.DeviceType = EOculusXRTrackedDeviceType::None;
}
}
#endif
return InteractionInfo;
}
FOculusXRGuardianTestResult UOculusXRFunctionLibrary::GetNodeGuardianIntersection(EOculusXRTrackedDeviceType DeviceType, EOculusXRBoundaryType BoundaryType)
{
FOculusXRGuardianTestResult InteractionInfo;
memset(&InteractionInfo, 0, sizeof(FOculusXRGuardianTestResult));
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
ovrpNode OvrpNode = OculusXRHMD::ToOvrpNode(DeviceType);
ovrpBoundaryType OvrpBoundaryType = ToOvrpBoundaryType(BoundaryType);
ovrpBoundaryTestResult TestResult;
if (OVRP_SUCCESS(FOculusXRHMDModule::GetPluginWrapper().TestBoundaryNode2(OvrpNode, ovrpBoundary_PlayArea, &TestResult)) && TestResult.IsTriggering)
{
InteractionInfo.IsTriggering = true;
InteractionInfo.DeviceType = OculusXRHMD::ToEOculusXRTrackedDeviceType(OvrpNode);
InteractionInfo.ClosestDistance = OculusXRHMD->ConvertFloat_M2U(TestResult.ClosestDistance);
InteractionInfo.ClosestPoint = OculusXRHMD->ScaleAndMovePointWithPlayer(TestResult.ClosestPoint);
InteractionInfo.ClosestPointNormal = OculusXRHMD->ConvertVector_M2U(TestResult.ClosestPointNormal);
}
}
#endif
return InteractionInfo;
}
void UOculusXRFunctionLibrary::SetGuardianVisibility(bool GuardianVisible)
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
FOculusXRHMDModule::GetPluginWrapper().SetBoundaryVisible2(GuardianVisible);
}
#endif
}
bool UOculusXRFunctionLibrary::GetSystemHmd3DofModeEnabled()
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
ovrpBool enabled;
return OVRP_SUCCESS(FOculusXRHMDModule::GetPluginWrapper().GetSystemHmd3DofModeEnabled(&enabled)) && enabled;
}
#endif
return false;
}
EOculusXRColorSpace UOculusXRFunctionLibrary::GetHmdColorDesc()
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
ovrpColorSpace HmdColorSpace;
if (OVRP_SUCCESS(FOculusXRHMDModule::GetPluginWrapper().GetHmdColorDesc(&HmdColorSpace)))
{
return (EOculusXRColorSpace)HmdColorSpace;
}
}
#endif
return EOculusXRColorSpace::Unknown;
}
void UOculusXRFunctionLibrary::SetClientColorDesc(EOculusXRColorSpace ColorSpace)
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
ovrpColorSpace ClientColorSpace = (ovrpColorSpace)ColorSpace;
#if PLATFORM_ANDROID
if (ClientColorSpace == ovrpColorSpace_Unknown)
{
ClientColorSpace = ovrpColorSpace_Quest;
}
#endif
FOculusXRHMDModule::GetPluginWrapper().SetClientColorDesc(ClientColorSpace);
}
#endif
}
void UOculusXRFunctionLibrary::SetLocalDimmingOn(bool LocalDimmingOn)
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
UE_LOG(LogHMD, Log, TEXT("SetLocalDimmingOn %d"), LocalDimmingOn);
FOculusXRHMDModule::GetPluginWrapper().SetLocalDimming(LocalDimmingOn);
}
#endif
}
bool UOculusXRFunctionLibrary::IsPassthroughSupported()
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
ovrpInsightPassthroughCapabilityFlags capabilities;
if (OVRP_SUCCESS(FOculusXRHMDModule::GetPluginWrapper().GetPassthroughCapabilityFlags(&capabilities)))
{
return (capabilities & ovrpInsightPassthroughCapabilityFlags::ovrpInsightPassthroughCapabilityFlags_Passthrough)
== ovrpInsightPassthroughCapabilityFlags::ovrpInsightPassthroughCapabilityFlags_Passthrough;
}
return false;
}
#endif
return false;
}
bool UOculusXRFunctionLibrary::IsColorPassthroughSupported()
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
ovrpInsightPassthroughCapabilityFlags capabilities;
if (OVRP_SUCCESS(FOculusXRHMDModule::GetPluginWrapper().GetPassthroughCapabilityFlags(&capabilities)))
{
return (capabilities & ovrpInsightPassthroughCapabilityFlags::ovrpInsightPassthroughCapabilityFlags_Color)
== ovrpInsightPassthroughCapabilityFlags::ovrpInsightPassthroughCapabilityFlags_Color;
}
return false;
}
#endif
return false;
}
void UOculusXRFunctionLibrary::StartEnvironmentDepth()
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
int CreateFlags = 0;
OculusXRHMD->StartEnvironmentDepth(CreateFlags);
}
#endif
}
void UOculusXRFunctionLibrary::StopEnvironmentDepth()
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
OculusXRHMD->StopEnvironmentDepth();
}
#endif
}
bool UOculusXRFunctionLibrary::IsEnvironmentDepthStarted()
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
return OculusXRHMD->IsEnvironmentDepthStarted();
}
#endif
return false;
}
void UOculusXRFunctionLibrary::SetEnvironmentDepthHandRemoval(bool RemoveHands)
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
OculusXRHMD->SetEnvironmentDepthHandRemoval(RemoveHands);
}
#endif
}
void UOculusXRFunctionLibrary::SetXROcclusionsMode(UObject* WorldContextObject, EOculusXROcclusionsMode Mode)
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
OculusXRHMD->EnableHardOcclusions(Mode == EOculusXROcclusionsMode::HardOcclusions);
}
#if defined(WITH_OCULUS_BRANCH)
WorldContextObject->GetWorld()->Scene->SetEnableXRPassthroughSoftOcclusions(Mode == EOculusXROcclusionsMode::SoftOcclusions);
#else
ensureMsgf(Mode != EOculusXROcclusionsMode::SoftOcclusions, TEXT("Soft occlusions are only supported with the Oculus branch of the Unreal Engine"));
#endif // defined(WITH_OCULUS_BRANCH)
#endif // OCULUS_HMD_SUPPORTED_PLATFORMS
}
void UOculusXRFunctionLibrary::SetEyeBufferSharpenType(EOculusXREyeBufferSharpenType EyeBufferSharpenType)
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
OculusXRHMD::FOculusXRHMD* OculusXRHMD = GetOculusXRHMD();
if (OculusXRHMD != nullptr)
{
switch (EyeBufferSharpenType)
{
case EOculusXREyeBufferSharpenType::SLST_Normal:
FOculusXRHMDModule::GetPluginWrapper().SetEyeBufferSharpenType(ovrpLayerSubmitFlag_EfficientSharpen);
break;
case EOculusXREyeBufferSharpenType::SLST_Quality:
FOculusXRHMDModule::GetPluginWrapper().SetEyeBufferSharpenType(ovrpLayerSubmitFlag_QualitySharpen);
break;
case EOculusXREyeBufferSharpenType::SLST_Auto:
FOculusXRHMDModule::GetPluginWrapper().SetEyeBufferSharpenType(ovrpLayerSubmitFlag_AutoLayerFilter);
break;
default:
FOculusXRHMDModule::GetPluginWrapper().SetEyeBufferSharpenType(ovrpLayerSubmitFlags(0));
break;
}
}
#endif
}
bool UOculusXRFunctionLibrary::IsPassthroughRecommended()
{
#if OCULUS_HMD_SUPPORTED_PLATFORMS
const OculusXRHMD::FOculusXRHMD* OculusHMD = GetOculusXRHMD();
if (OculusHMD != nullptr)
{
ovrpPassthroughPreferences Preferences;
if (OVRP_SUCCESS(FOculusXRHMDModule::GetPluginWrapper().GetPassthroughPreferences(&Preferences)))
{
return (Preferences.Flags & ovrpPassthroughPreferenceFlags::ovrpPassthroughPreferenceFlags_DefaultToActive)
== ovrpPassthroughPreferenceFlags::ovrpPassthroughPreferenceFlags_DefaultToActive;
};
}
#endif
return false;
}
#undef LOCTEXT_NAMESPACE