Android build settings + metaxr
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
#include "OculusXRAnchorBPFunctionLibrary.h"
|
||||
|
||||
#include "Engine/GameEngine.h"
|
||||
#include "OculusXRAnchorsModule.h"
|
||||
#include "OculusXRHMD.h"
|
||||
#include "OculusXRSpatialAnchorComponent.h"
|
||||
#include "OculusXRAnchorsPrivate.h"
|
||||
#include "OculusXRAnchorManager.h"
|
||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||
|
||||
AActor* UOculusXRAnchorBPFunctionLibrary::SpawnActorWithAnchorHandle(UObject* WorldContextObject, FOculusXRUInt64 Handle, FOculusXRUUID UUID, EOculusXRSpaceStorageLocation Location, UClass* ActorClass,
|
||||
AActor* Owner, APawn* Instigator, ESpawnActorCollisionHandlingMethod CollisionHandlingMethod)
|
||||
{
|
||||
FActorSpawnParameters SpawnInfo;
|
||||
SpawnInfo.Owner = Owner;
|
||||
SpawnInfo.Instigator = Instigator;
|
||||
SpawnInfo.ObjectFlags |= RF_Transient;
|
||||
SpawnInfo.SpawnCollisionHandlingOverride = CollisionHandlingMethod;
|
||||
|
||||
UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
|
||||
if (World == nullptr)
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("Invalid WorldContext Object for SpawnActorWithAnchorHandle."));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AActor* NewSpatialAnchorActor = World->SpawnActor(ActorClass, nullptr, nullptr, SpawnInfo);
|
||||
if (NewSpatialAnchorActor == nullptr)
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("Failed to spawn Actor in SpawnActorWithAnchorHandle"));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
UOculusXRSpatialAnchorComponent* SpatialAnchorComponent = NewSpatialAnchorActor->FindComponentByClass<UOculusXRSpatialAnchorComponent>();
|
||||
if (SpatialAnchorComponent == nullptr)
|
||||
{
|
||||
SpatialAnchorComponent = Cast<UOculusXRSpatialAnchorComponent>(NewSpatialAnchorActor->AddComponentByClass(UOculusXRSpatialAnchorComponent::StaticClass(), false, FTransform::Identity, false));
|
||||
}
|
||||
|
||||
if (!IsValid(SpatialAnchorComponent))
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("Failed to find or spawn Spatial Anchor component in SpawnActorWithAnchorHandle"));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SpatialAnchorComponent->SetHandle(Handle);
|
||||
SpatialAnchorComponent->SetUUID(UUID);
|
||||
SpatialAnchorComponent->SetStoredLocation(Location, true);
|
||||
return NewSpatialAnchorActor;
|
||||
}
|
||||
|
||||
AActor* UOculusXRAnchorBPFunctionLibrary::SpawnActorWithAnchorQueryResults(UObject* WorldContextObject, const FOculusXRSpaceQueryResult& QueryResult, UClass* ActorClass, AActor* Owner, APawn* Instigator, ESpawnActorCollisionHandlingMethod CollisionHandlingMethod)
|
||||
{
|
||||
return SpawnActorWithAnchorHandle(WorldContextObject, QueryResult.Space, QueryResult.UUID, QueryResult.Location, ActorClass, Owner, Instigator, CollisionHandlingMethod);
|
||||
}
|
||||
|
||||
bool UOculusXRAnchorBPFunctionLibrary::GetAnchorComponentStatus(AActor* TargetActor, EOculusXRSpaceComponentType ComponentType, bool& bIsEnabled)
|
||||
{
|
||||
UOculusXRAnchorComponent* AnchorComponent = Cast<UOculusXRAnchorComponent>(TargetActor->GetComponentByClass(UOculusXRAnchorComponent::StaticClass()));
|
||||
|
||||
if (!IsValid(AnchorComponent))
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("Invalid Anchor Component provided to GetAnchorComponentStatus"));
|
||||
bIsEnabled = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool bOutIsEnabled = false;
|
||||
bool bIsChangePending = false;
|
||||
|
||||
EOculusXRAnchorResult::Type AnchorResult;
|
||||
bool bDidCallStart = OculusXRAnchors::FOculusXRAnchors::GetAnchorComponentStatus(AnchorComponent, ComponentType, bOutIsEnabled, bIsChangePending, AnchorResult);
|
||||
if (!bDidCallStart)
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("Failed to start call to internal GetAnchorComponentStatus"));
|
||||
bIsEnabled = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
bIsEnabled = bOutIsEnabled;
|
||||
return bIsEnabled;
|
||||
}
|
||||
|
||||
bool UOculusXRAnchorBPFunctionLibrary::GetAnchorTransformByHandle(const FOculusXRUInt64& Handle, FTransform& OutTransform)
|
||||
{
|
||||
FOculusXRAnchorLocationFlags AnchorFlags(0);
|
||||
return TryGetAnchorTransformByHandle(Handle, OutTransform, AnchorFlags);
|
||||
}
|
||||
|
||||
bool UOculusXRAnchorBPFunctionLibrary::TryGetAnchorTransformByHandle(const FOculusXRUInt64& Handle, FTransform& OutTransform, FOculusXRAnchorLocationFlags& OutLocationFlags, EOculusXRAnchorSpace Space)
|
||||
{
|
||||
auto result = OculusXRAnchors::FOculusXRAnchorManager::TryGetAnchorTransform(Handle, OutTransform, OutLocationFlags, Space);
|
||||
return IsAnchorResultSuccess(result);
|
||||
}
|
||||
|
||||
FString UOculusXRAnchorBPFunctionLibrary::AnchorHandleToString(const FOculusXRUInt64 Value)
|
||||
{
|
||||
return FString::Printf(TEXT("%llu"), Value.Value);
|
||||
}
|
||||
|
||||
FString UOculusXRAnchorBPFunctionLibrary::AnchorUUIDToString(const FOculusXRUUID& Value)
|
||||
{
|
||||
return Value.ToString();
|
||||
}
|
||||
|
||||
FOculusXRUUID UOculusXRAnchorBPFunctionLibrary::StringToAnchorUUID(const FString& Value)
|
||||
{
|
||||
// Static size for the max length of the string, two chars per hex digit, 16 digits.
|
||||
checkf(Value.Len() == 32, TEXT("'%s' is not a valid UUID"), *Value);
|
||||
|
||||
ovrpUuid newID;
|
||||
HexToBytes(Value, newID.data);
|
||||
|
||||
return FOculusXRUUID(newID.data);
|
||||
}
|
||||
bool UOculusXRAnchorBPFunctionLibrary::IsAnchorResultSuccess(EOculusXRAnchorResult::Type result)
|
||||
{
|
||||
#if OCULUS_HMD_SUPPORTED_PLATFORMS
|
||||
return OVRP_SUCCESS(result);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
const UOculusXRBaseAnchorComponent* UOculusXRAnchorBPFunctionLibrary::GetAnchorComponent(const FOculusXRSpaceQueryResult& QueryResult, EOculusXRSpaceComponentType ComponentType, UObject* Outer)
|
||||
{
|
||||
auto& anchorsModule = FModuleManager::GetModuleChecked<IOculusXRAnchorsModule>("OculusXRAnchors");
|
||||
return anchorsModule.CreateAnchorComponent(QueryResult.Space.Value, ComponentType, Outer);
|
||||
}
|
||||
@@ -0,0 +1,209 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
#include "OculusXRAnchorComponent.h"
|
||||
#include "OculusXRAnchors.h"
|
||||
#include "OculusXRAnchorsModule.h"
|
||||
#include "OculusXRHMD.h"
|
||||
#include "OculusXRAnchorBPFunctionLibrary.h"
|
||||
#include "OculusXRAnchorsPrivate.h"
|
||||
#include "GameFramework/PlayerController.h"
|
||||
|
||||
#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
|
||||
static TAutoConsoleVariable<int32> CVarOculusXRVerboseAnchorDebugXR(
|
||||
TEXT("ovr.OculusXRVerboseAnchorDebug"),
|
||||
0,
|
||||
TEXT("Enables or disables verbose logging for Oculus anchors.\n")
|
||||
TEXT("<=0: disabled (no printing)\n")
|
||||
TEXT(" 1: enabled (verbose logging)\n"));
|
||||
#endif
|
||||
|
||||
UOculusXRAnchorComponent::UOculusXRAnchorComponent(const FObjectInitializer& ObjectInitializer)
|
||||
: Super(ObjectInitializer)
|
||||
, bUpdateHeadSpaceTransform(true)
|
||||
, AnchorHandle(0)
|
||||
, StorageLocations(0)
|
||||
{
|
||||
AnchorHandle = 0;
|
||||
PrimaryComponentTick.bCanEverTick = true;
|
||||
PrimaryComponentTick.bStartWithTickEnabled = true;
|
||||
PrimaryComponentTick.TickGroup = TG_PostUpdateWork;
|
||||
}
|
||||
|
||||
void UOculusXRAnchorComponent::BeginPlay()
|
||||
{
|
||||
Super::BeginPlay();
|
||||
|
||||
UWorld* World = GetWorld();
|
||||
if (IsValid(World))
|
||||
{
|
||||
APlayerController* PlayerController = World->GetFirstPlayerController();
|
||||
if (IsValid(PlayerController))
|
||||
{
|
||||
PlayerCameraManager = PlayerController->PlayerCameraManager;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UOculusXRAnchorComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
|
||||
{
|
||||
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
|
||||
UpdateAnchorTransform();
|
||||
}
|
||||
|
||||
void UOculusXRAnchorComponent::EndPlay(const EEndPlayReason::Type EndPlayReason)
|
||||
{
|
||||
Super::EndPlay(EndPlayReason);
|
||||
|
||||
if (HasValidHandle())
|
||||
{
|
||||
EOculusXRAnchorResult::Type AnchorResult;
|
||||
OculusXRAnchors::FOculusXRAnchors::DestroyAnchor(AnchorHandle.GetValue(), AnchorResult);
|
||||
}
|
||||
}
|
||||
|
||||
FOculusXRUInt64 UOculusXRAnchorComponent::GetHandle() const
|
||||
{
|
||||
return AnchorHandle;
|
||||
}
|
||||
|
||||
void UOculusXRAnchorComponent::SetHandle(FOculusXRUInt64 Handle)
|
||||
{
|
||||
AnchorHandle = Handle;
|
||||
}
|
||||
|
||||
bool UOculusXRAnchorComponent::HasValidHandle() const
|
||||
{
|
||||
return AnchorHandle != FOculusXRUInt64(0);
|
||||
}
|
||||
|
||||
FOculusXRUUID UOculusXRAnchorComponent::GetUUID() const
|
||||
{
|
||||
return AnchorUUID;
|
||||
}
|
||||
|
||||
void UOculusXRAnchorComponent::SetUUID(FOculusXRUUID NewUUID)
|
||||
{
|
||||
if (AnchorUUID.IsValidUUID())
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("Anchor component already has valid UUID, cannot re-assign a new UUID. Component: %s -- Space: %llu -- UUID: %s"),
|
||||
*GetName(), AnchorHandle.GetValue(), *AnchorUUID.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!NewUUID.IsValidUUID())
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("New UUID provided to component is invalid, cannot assign. Component: %s -- Space: %llu"), *GetName(), AnchorHandle.GetValue());
|
||||
return;
|
||||
}
|
||||
|
||||
UE_LOG(LogOculusXRAnchors, Verbose, TEXT("Assigned new Oculus UUID: %s"), *NewUUID.ToString());
|
||||
|
||||
AnchorUUID = NewUUID;
|
||||
}
|
||||
|
||||
bool UOculusXRAnchorComponent::IsStoredAtLocation(EOculusXRSpaceStorageLocation Location) const
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Verbose, TEXT("Anchor UUID: %s - Saved Local: %d - Saved Cloud: %d"),
|
||||
*GetUUID().ToString(),
|
||||
StorageLocations & static_cast<int32>(EOculusXRSpaceStorageLocation::Local),
|
||||
StorageLocations & static_cast<int32>(EOculusXRSpaceStorageLocation::Cloud));
|
||||
|
||||
return (StorageLocations & static_cast<int32>(Location)) > 0;
|
||||
}
|
||||
|
||||
void UOculusXRAnchorComponent::SetStoredLocation(EOculusXRSpaceStorageLocation Location, bool Stored)
|
||||
{
|
||||
if (Stored)
|
||||
{
|
||||
StorageLocations |= static_cast<int32>(Location);
|
||||
}
|
||||
else
|
||||
{
|
||||
StorageLocations = StorageLocations & ~static_cast<int32>(Location);
|
||||
}
|
||||
|
||||
UE_LOG(LogOculusXRAnchors, Verbose, TEXT("Anchor UUID: %s - Saved Local: %d - Saved Cloud: %d"),
|
||||
*GetUUID().ToString(),
|
||||
StorageLocations & static_cast<int32>(EOculusXRSpaceStorageLocation::Local),
|
||||
StorageLocations & static_cast<int32>(EOculusXRSpaceStorageLocation::Cloud));
|
||||
}
|
||||
|
||||
bool UOculusXRAnchorComponent::IsSaved() const
|
||||
{
|
||||
return StorageLocations > 0;
|
||||
}
|
||||
|
||||
void UOculusXRAnchorComponent::UpdateAnchorTransform() const
|
||||
{
|
||||
if (GetWorld() == nullptr)
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("Unable to retrieve World Context"));
|
||||
return;
|
||||
}
|
||||
|
||||
AActor* Parent = GetOwner();
|
||||
if (Parent)
|
||||
{
|
||||
if (AnchorHandle.Value)
|
||||
{
|
||||
FTransform OutTransform;
|
||||
if (UOculusXRAnchorBPFunctionLibrary::GetAnchorTransformByHandle(AnchorHandle, OutTransform))
|
||||
{
|
||||
#if WITH_EDITOR
|
||||
// Link only head-space transform update
|
||||
if (bUpdateHeadSpaceTransform && PlayerCameraManager != nullptr)
|
||||
{
|
||||
FTransform MainCameraTransform;
|
||||
MainCameraTransform.SetLocation(PlayerCameraManager->GetCameraLocation());
|
||||
MainCameraTransform.SetRotation(FQuat(PlayerCameraManager->GetCameraRotation()));
|
||||
|
||||
if (!ToWorldSpacePose(MainCameraTransform, OutTransform))
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Display, TEXT("Was not able to transform anchor to world space pose"));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
|
||||
if (CVarOculusXRVerboseAnchorDebugXR.GetValueOnGameThread() > 0)
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Display, TEXT("UpdateAnchor Pos %s"), *OutTransform.GetLocation().ToString());
|
||||
UE_LOG(LogOculusXRAnchors, Display, TEXT("UpdateAnchor Rot %s"), *OutTransform.GetRotation().ToString());
|
||||
}
|
||||
#endif
|
||||
Parent->SetActorLocationAndRotation(OutTransform.GetLocation(), OutTransform.GetRotation(), false, 0, ETeleportType::ResetPhysics);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool UOculusXRAnchorComponent::ToWorldSpacePose(FTransform CameraTransform, FTransform& OutTrackingSpaceTransform) const
|
||||
{
|
||||
OculusXRHMD::FOculusXRHMD* OculusXRHMD = OculusXRHMD::FOculusXRHMD::GetOculusXRHMD();
|
||||
if (!OculusXRHMD)
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("Unable to retrieve OculusXRHMD, cannot calculate anchor world space pose."));
|
||||
return false;
|
||||
}
|
||||
|
||||
OculusXRHMD::FPose MainCameraPose(CameraTransform.GetRotation(), CameraTransform.GetLocation());
|
||||
OculusXRHMD::FPose TrackingSpacePose(OutTrackingSpaceTransform.GetRotation(), OutTrackingSpaceTransform.GetLocation());
|
||||
|
||||
FVector OutHeadPosition;
|
||||
FQuat OutHeadOrientation;
|
||||
const bool bGetPose = OculusXRHMD->GetCurrentPose(OculusXRHMD->HMDDeviceId, OutHeadOrientation, OutHeadPosition);
|
||||
if (!bGetPose)
|
||||
return false;
|
||||
|
||||
OculusXRHMD::FPose HeadPose(OutHeadOrientation, OutHeadPosition);
|
||||
|
||||
OculusXRHMD::FPose poseInHeadSpace = HeadPose.Inverse() * TrackingSpacePose;
|
||||
|
||||
// To world space pose
|
||||
const OculusXRHMD::FPose WorldTrackingSpacePose = MainCameraPose * poseInHeadSpace;
|
||||
|
||||
OutTrackingSpaceTransform.SetLocation(WorldTrackingSpacePose.Position);
|
||||
OutTrackingSpaceTransform.SetRotation(WorldTrackingSpacePose.Orientation);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
#include "OculusXRAnchorComponents.h"
|
||||
|
||||
#include "OculusXRAnchorBPFunctionLibrary.h"
|
||||
#include "OculusXRAnchorManager.h"
|
||||
#include "OculusXRSpatialAnchorComponent.h"
|
||||
|
||||
bool UOculusXRBaseAnchorComponent::IsComponentEnabled() const
|
||||
{
|
||||
bool OutEnabled;
|
||||
bool OutChangePending;
|
||||
|
||||
auto OutResult = OculusXRAnchors::FOculusXRAnchorManager::GetAnchorComponentStatus(Space, Type, OutEnabled, OutChangePending);
|
||||
return UOculusXRAnchorBPFunctionLibrary::IsAnchorResultSuccess(OutResult) && OutEnabled;
|
||||
}
|
||||
|
||||
EOculusXRSpaceComponentType UOculusXRBaseAnchorComponent::GetType() const
|
||||
{
|
||||
return Type;
|
||||
}
|
||||
|
||||
uint64 UOculusXRBaseAnchorComponent::GetSpace() const
|
||||
{
|
||||
return Space;
|
||||
}
|
||||
|
||||
bool UOculusXRLocatableAnchorComponent::GetTransform(FTransform& outTransform) const
|
||||
{
|
||||
ensure(IsComponentEnabled());
|
||||
|
||||
if (!UOculusXRAnchorBPFunctionLibrary::GetAnchorTransformByHandle(Space, outTransform))
|
||||
{
|
||||
UE_LOG(LogOculusSpatialAnchor, Warning, TEXT("Fetching transform failed."));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UOculusXRSpaceContainerAnchorComponent::GetUUIDs(TArray<FOculusXRUUID>& outUUIDs) const
|
||||
{
|
||||
ensure(IsComponentEnabled());
|
||||
|
||||
if (!OculusXRAnchors::FOculusXRAnchorManager::GetAnchorContainerUUIDs(Space, outUUIDs))
|
||||
{
|
||||
UE_LOG(LogOculusSpatialAnchor, Warning, TEXT("Fetching container uuids failed."));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
#include "OculusXRAnchorDelegates.h"
|
||||
|
||||
FOculusXRAnchorEventDelegates::FOculusXRSpatialAnchorCreateCompleteDelegate FOculusXRAnchorEventDelegates::OculusSpatialAnchorCreateComplete;
|
||||
|
||||
FOculusXRAnchorEventDelegates::FOculusXRSpaceSetComponentStatusCompleteDelegate FOculusXRAnchorEventDelegates::OculusSpaceSetComponentStatusComplete;
|
||||
|
||||
FOculusXRAnchorEventDelegates::FOculusXRSpaceQueryResultsDelegate FOculusXRAnchorEventDelegates::OculusSpaceQueryResults;
|
||||
|
||||
FOculusXRAnchorEventDelegates::FOculusXRSpaceQueryResultDelegate FOculusXRAnchorEventDelegates::OculusSpaceQueryResult;
|
||||
|
||||
FOculusXRAnchorEventDelegates::FOculusXRSpaceQueryCompleteDelegate FOculusXRAnchorEventDelegates::OculusSpaceQueryComplete;
|
||||
|
||||
FOculusXRAnchorEventDelegates::FOculusXRSpaceSaveCompleteDelegate FOculusXRAnchorEventDelegates::OculusSpaceSaveComplete;
|
||||
|
||||
FOculusXRAnchorEventDelegates::FOculusXRSpaceListSaveCompleteDelegate FOculusXRAnchorEventDelegates::OculusSpaceListSaveComplete;
|
||||
|
||||
FOculusXRAnchorEventDelegates::FOculusXRSpaceEraseCompleteDelegate FOculusXRAnchorEventDelegates::OculusSpaceEraseComplete;
|
||||
|
||||
FOculusXRAnchorEventDelegates::FOculusXRSpaceShareCompleteDelegate FOculusXRAnchorEventDelegates::OculusSpaceShareComplete;
|
||||
|
||||
FOculusXRAnchorEventDelegates::FOculusXRAnchorsDiscoverCompleteDelegate FOculusXRAnchorEventDelegates::OculusAnchorsDiscoverComplete;
|
||||
|
||||
FOculusXRAnchorEventDelegates::FOculusXRAnchorsDiscoverResultsDelegate FOculusXRAnchorEventDelegates::OculusAnchorsDiscoverResults;
|
||||
|
||||
FOculusXRAnchorEventDelegates::FOculusXRAnchorsSaveCompleteDelegate FOculusXRAnchorEventDelegates::OculusAnchorsSaveComplete;
|
||||
|
||||
FOculusXRAnchorEventDelegates::FOculusXRAnchorsEraseCompleteDelegate FOculusXRAnchorEventDelegates::OculusAnchorsEraseComplete;
|
||||
|
||||
FOculusXRAnchorEventDelegates::FOculusXRShareAnchorsCompleteDelegate FOculusXRAnchorEventDelegates::OculusShareAnchorsComplete;
|
||||
@@ -0,0 +1,612 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
#include "OculusXRAnchorFunctionsOVR.h"
|
||||
#include "OculusXRHMD.h"
|
||||
#include "OculusXRAnchorsModule.h"
|
||||
#include "OculusXRAnchorDelegates.h"
|
||||
#include "OculusXRAnchorBPFunctionLibrary.h"
|
||||
#include "OculusXRAnchorTypesPrivate.h"
|
||||
#include "OculusXRAnchorsUtil.h"
|
||||
|
||||
ovrpSpaceQueryInfo2 ToOvrpSpaceQuery(const FOculusXRSpaceQueryInfo& UEQueryInfo)
|
||||
{
|
||||
static const int32 MaxIdsInFilter = 1024;
|
||||
static const int32 MaxComponentTypesInFilter = 1;
|
||||
|
||||
ovrpSpaceQueryInfo2 Result = {};
|
||||
|
||||
Result.queryType = ovrpSpaceQueryType_Action;
|
||||
Result.actionType = ovrpSpaceQueryActionType_Load;
|
||||
|
||||
Result.maxQuerySpaces = UEQueryInfo.MaxQuerySpaces;
|
||||
Result.timeout = static_cast<double>(UEQueryInfo.Timeout);
|
||||
|
||||
switch (UEQueryInfo.Location)
|
||||
{
|
||||
case EOculusXRSpaceStorageLocation::Invalid:
|
||||
Result.location = ovrpSpaceStorageLocation_Invalid;
|
||||
break;
|
||||
case EOculusXRSpaceStorageLocation::Local:
|
||||
Result.location = ovrpSpaceStorageLocation_Local;
|
||||
break;
|
||||
case EOculusXRSpaceStorageLocation::Cloud:
|
||||
Result.location = ovrpSpaceStorageLocation_Cloud;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (UEQueryInfo.FilterType)
|
||||
{
|
||||
case EOculusXRSpaceQueryFilterType::None:
|
||||
Result.filterType = ovrpSpaceQueryFilterType_None;
|
||||
break;
|
||||
case EOculusXRSpaceQueryFilterType::FilterByIds:
|
||||
Result.filterType = ovrpSpaceQueryFilterType_Ids;
|
||||
break;
|
||||
case EOculusXRSpaceQueryFilterType::FilterByComponentType:
|
||||
Result.filterType = ovrpSpaceQueryFilterType_Components;
|
||||
break;
|
||||
case EOculusXRSpaceQueryFilterType::FilterByGroup:
|
||||
Result.filterType = ovrpSpaceQueryFilterType_GroupUuid;
|
||||
break;
|
||||
}
|
||||
|
||||
Result.IdInfo.numIds = FMath::Min(MaxIdsInFilter, UEQueryInfo.IDFilter.Num());
|
||||
for (int i = 0; i < Result.IdInfo.numIds; ++i)
|
||||
{
|
||||
ovrpUuid OvrUuid;
|
||||
FMemory::Memcpy(OvrUuid.data, UEQueryInfo.IDFilter[i].UUIDBytes);
|
||||
Result.IdInfo.ids[i] = OvrUuid;
|
||||
}
|
||||
|
||||
if (UEQueryInfo.ComponentFilter.Num() > 1)
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("Query info has more than one component. Using first component only."));
|
||||
}
|
||||
|
||||
Result.componentsInfo.numComponents = FMath::Min(MaxComponentTypesInFilter, UEQueryInfo.ComponentFilter.Num());
|
||||
for (int i = 0; i < Result.componentsInfo.numComponents; ++i)
|
||||
{
|
||||
Result.componentsInfo.components[i] = ConvertToOvrpComponentType(UEQueryInfo.ComponentFilter[i]);
|
||||
}
|
||||
|
||||
FMemory::Memcpy(Result.groupUuidInfo.groupUuid.data, UEQueryInfo.GroupUUIDFilter.UUIDBytes);
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorFunctionsOVR::CreateAnchor(const FTransform& InTransform, uint64& OutRequestId, const FTransform& CameraTransform)
|
||||
{
|
||||
OculusXRHMD::FOculusXRHMD* HMD = OculusXRHMD::FOculusXRHMD::GetOculusXRHMD();
|
||||
if (!HMD)
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("FOculusAnchorManager::CreateAnchor failed to retrieve HMD."));
|
||||
return EOculusXRAnchorResult::Failure;
|
||||
}
|
||||
|
||||
ovrpTrackingOrigin TrackingOriginType;
|
||||
ovrpPosef Posef;
|
||||
double Time = 0;
|
||||
|
||||
const FTransform TrackingToWorld = HMD->GetLastTrackingToWorld();
|
||||
|
||||
// convert to tracking space
|
||||
const FQuat TrackingSpaceOrientation = TrackingToWorld.Inverse().TransformRotation(InTransform.Rotator().Quaternion());
|
||||
const FVector TrackingSpacePosition = TrackingToWorld.Inverse().TransformPosition(InTransform.GetLocation());
|
||||
|
||||
const OculusXRHMD::FPose TrackingSpacePose(TrackingSpaceOrientation, TrackingSpacePosition);
|
||||
|
||||
#if WITH_EDITOR
|
||||
// Link only head space position update
|
||||
FVector OutHeadPosition;
|
||||
FQuat OutHeadOrientation;
|
||||
const bool bGetPose = HMD->GetCurrentPose(HMD->HMDDeviceId, OutHeadOrientation, OutHeadPosition);
|
||||
if (!bGetPose)
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("FOculusAnchorManager::CreateAnchor failed to get current headset pose."));
|
||||
return EOculusXRAnchorResult::Failure;
|
||||
}
|
||||
|
||||
OculusXRHMD::FPose HeadPose(OutHeadOrientation, OutHeadPosition);
|
||||
|
||||
OculusXRHMD::FPose MainCameraPose(CameraTransform.GetRotation(), CameraTransform.GetLocation());
|
||||
OculusXRHMD::FPose PoseInHeadSpace = MainCameraPose.Inverse() * TrackingSpacePose;
|
||||
|
||||
// To world space pose
|
||||
OculusXRHMD::FPose WorldPose = HeadPose * PoseInHeadSpace;
|
||||
|
||||
const bool bConverted = HMD->ConvertPose(WorldPose, Posef);
|
||||
#else
|
||||
const bool bConverted = HMD->ConvertPose(TrackingSpacePose, Posef);
|
||||
#endif
|
||||
|
||||
if (!bConverted)
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("FOculusAnchorManager::CreateAnchor failed to convert pose."));
|
||||
return EOculusXRAnchorResult::Failure;
|
||||
}
|
||||
|
||||
FOculusXRHMDModule::GetPluginWrapper().GetTrackingOriginType2(&TrackingOriginType);
|
||||
FOculusXRHMDModule::GetPluginWrapper().GetTimeInSeconds(&Time);
|
||||
|
||||
const ovrpSpatialAnchorCreateInfo SpatialAnchorCreateInfo = {
|
||||
TrackingOriginType,
|
||||
Posef,
|
||||
Time
|
||||
};
|
||||
|
||||
const ovrpResult Result = FOculusXRHMDModule::GetPluginWrapper().CreateSpatialAnchor(&SpatialAnchorCreateInfo, &OutRequestId);
|
||||
UE_LOG(LogOculusXRAnchors, Verbose, TEXT("CreateAnchor Request ID: %llu"), OutRequestId);
|
||||
|
||||
if (OVRP_FAILURE(Result))
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Error, TEXT("FOculusAnchorManager::CreateAnchor failed. Result: %d"), Result);
|
||||
}
|
||||
|
||||
return OculusXRAnchors::GetResultFromOVRResult(Result);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorFunctionsOVR::DestroyAnchor(uint64 AnchorHandle)
|
||||
{
|
||||
const ovrpResult Result = FOculusXRHMDModule::GetPluginWrapper().DestroySpace(static_cast<ovrpSpace*>(&AnchorHandle));
|
||||
|
||||
UE_LOG(LogOculusXRAnchors, Verbose, TEXT("DestroyAnchor -- ID: %llu"), AnchorHandle);
|
||||
|
||||
return OculusXRAnchors::GetResultFromOVRResult(Result);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorFunctionsOVR::TryGetAnchorTransform(uint64 AnchorHandle, FTransform& OutTransform, FOculusXRAnchorLocationFlags& OutLocationFlags, EOculusXRAnchorSpace Space)
|
||||
{
|
||||
OculusXRHMD::FOculusXRHMD* OutHMD = OculusXRHMD::FOculusXRHMD::GetOculusXRHMD();
|
||||
if (!OutHMD)
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("Unable to retrieve OculusXRHMD, cannot calculate anchor transform."));
|
||||
return EOculusXRAnchorResult::Failure_InvalidOperation;
|
||||
}
|
||||
|
||||
ovrpTrackingOrigin ovrpOrigin = ovrpTrackingOrigin_EyeLevel;
|
||||
const bool bTrackingOriginSuccess = OVRP_SUCCESS(FOculusXRHMDModule::GetPluginWrapper().GetTrackingOriginType2(&ovrpOrigin));
|
||||
if (!bTrackingOriginSuccess)
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("Unable to get tracking origin, cannot calculate anchor transform."));
|
||||
return EOculusXRAnchorResult::Failure_InvalidOperation;
|
||||
}
|
||||
|
||||
OutTransform = FTransform::Identity;
|
||||
OutLocationFlags = FOculusXRAnchorLocationFlags(0);
|
||||
|
||||
const ovrpUInt64 ovrpSpace = AnchorHandle;
|
||||
ovrpSpaceLocationf ovrpSpaceLocation{};
|
||||
|
||||
const ovrpResult result = FOculusXRHMDModule::GetPluginWrapper().LocateSpace2(&ovrpSpaceLocation, &ovrpSpace, ovrpOrigin);
|
||||
if (OVRP_SUCCESS(result))
|
||||
{
|
||||
OutLocationFlags = FOculusXRAnchorLocationFlags(ovrpSpaceLocation.locationFlags);
|
||||
if (OutLocationFlags.IsValid())
|
||||
{
|
||||
OculusXRHMD::FPose Pose;
|
||||
OutHMD->ConvertPose(ovrpSpaceLocation.pose, Pose);
|
||||
switch (Space)
|
||||
{
|
||||
case EOculusXRAnchorSpace::World:
|
||||
{
|
||||
const FTransform trackingToWorld = OutHMD->GetLastTrackingToWorld();
|
||||
OutTransform.SetLocation(trackingToWorld.TransformPosition(Pose.Position));
|
||||
OutTransform.SetRotation(FRotator(trackingToWorld.TransformRotation(FQuat(Pose.Orientation))).Quaternion());
|
||||
}
|
||||
break;
|
||||
case EOculusXRAnchorSpace::Tracking:
|
||||
{
|
||||
OutTransform.SetLocation(Pose.Position);
|
||||
OutTransform.SetRotation(FRotator(FQuat(Pose.Orientation)).Quaternion());
|
||||
}
|
||||
break;
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
return EOculusXRAnchorResult::Failure_OperationFailed;
|
||||
}
|
||||
}
|
||||
|
||||
return OculusXRAnchors::GetResultFromOVRResult(result);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorFunctionsOVR::SetAnchorComponentStatus(uint64 AnchorHandle, EOculusXRSpaceComponentType ComponentType, bool Enable, float Timeout, uint64& OutRequestId)
|
||||
{
|
||||
ovrpSpaceComponentType ovrpType = ConvertToOvrpComponentType(ComponentType);
|
||||
const ovrpUInt64 OVRPSpace = AnchorHandle;
|
||||
|
||||
// validate existing status
|
||||
ovrpBool isEnabled = false;
|
||||
ovrpBool changePending = false;
|
||||
const ovrpResult getComponentStatusResult = FOculusXRHMDModule::GetPluginWrapper().GetSpaceComponentStatus(&OVRPSpace, ovrpType, &isEnabled, &changePending);
|
||||
|
||||
bool isStatusChangingOrSame = (static_cast<bool>(isEnabled) == Enable && !changePending) || (static_cast<bool>(isEnabled) != Enable && changePending);
|
||||
if (OVRP_SUCCESS(getComponentStatusResult) && isStatusChangingOrSame)
|
||||
{
|
||||
return EOculusXRAnchorResult::Success;
|
||||
}
|
||||
|
||||
// set status
|
||||
const ovrpResult Result = FOculusXRHMDModule::GetPluginWrapper().SetSpaceComponentStatus(
|
||||
&OVRPSpace,
|
||||
ovrpType,
|
||||
Enable,
|
||||
Timeout,
|
||||
&OutRequestId);
|
||||
|
||||
UE_LOG(LogOculusXRAnchors, Verbose, TEXT("SetSpaceComponentStatus Request ID: %llu"), OutRequestId);
|
||||
|
||||
return OculusXRAnchors::GetResultFromOVRResult(Result);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorFunctionsOVR::GetAnchorComponentStatus(uint64 AnchorHandle, EOculusXRSpaceComponentType ComponentType, bool& OutEnabled, bool& OutChangePending)
|
||||
{
|
||||
const ovrpUInt64 OVRPSpace = AnchorHandle;
|
||||
ovrpBool OutOvrpEnabled = ovrpBool_False;
|
||||
ovrpBool OutOvrpChangePending = ovrpBool_False;
|
||||
|
||||
ovrpSpaceComponentType ovrpType = ConvertToOvrpComponentType(ComponentType);
|
||||
|
||||
const ovrpResult Result = FOculusXRHMDModule::GetPluginWrapper().GetSpaceComponentStatus(
|
||||
&OVRPSpace,
|
||||
ovrpType,
|
||||
&OutOvrpEnabled,
|
||||
&OutOvrpChangePending);
|
||||
|
||||
OutEnabled = (OutOvrpEnabled == ovrpBool_True);
|
||||
OutChangePending = (OutOvrpChangePending == ovrpBool_True);
|
||||
|
||||
return OculusXRAnchors::GetResultFromOVRResult(Result);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorFunctionsOVR::GetSupportedAnchorComponents(uint64 AnchorHandle, TArray<EOculusXRSpaceComponentType>& OutSupportedTypes)
|
||||
{
|
||||
ovrpSpace ovrSpace = AnchorHandle;
|
||||
TArray<ovrpSpaceComponentType> ovrComponentTypes;
|
||||
ovrpUInt32 input = 0;
|
||||
ovrpUInt32 output = 0;
|
||||
|
||||
ovrpResult enumerateResult = FOculusXRHMDModule::GetPluginWrapper().EnumerateSpaceSupportedComponents(&ovrSpace, input, &output, nullptr);
|
||||
if (!OVRP_SUCCESS(enumerateResult))
|
||||
{
|
||||
return OculusXRAnchors::GetResultFromOVRResult(enumerateResult);
|
||||
}
|
||||
|
||||
input = output;
|
||||
ovrComponentTypes.SetNumZeroed(output);
|
||||
|
||||
enumerateResult = FOculusXRHMDModule::GetPluginWrapper().EnumerateSpaceSupportedComponents(&ovrSpace, input, &output, ovrComponentTypes.GetData());
|
||||
if (!OVRP_SUCCESS(enumerateResult))
|
||||
{
|
||||
return OculusXRAnchors::GetResultFromOVRResult(enumerateResult);
|
||||
}
|
||||
|
||||
OutSupportedTypes.SetNumZeroed(ovrComponentTypes.Num());
|
||||
for (int i = 0; i < ovrComponentTypes.Num(); ++i)
|
||||
{
|
||||
OutSupportedTypes[i] = ConvertToUEComponentType(ovrComponentTypes[i]);
|
||||
}
|
||||
|
||||
return OculusXRAnchors::GetResultFromOVRResult(enumerateResult);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorFunctionsOVR::GetAnchorContainerUUIDs(uint64 AnchorHandle, TArray<FOculusXRUUID>& OutUUIDs)
|
||||
{
|
||||
TArray<ovrpUuid> ovrUuidArray;
|
||||
|
||||
// Get the number of elements in the container
|
||||
ovrpSpaceContainer ovrSpaceContainer = {};
|
||||
ovrSpaceContainer.uuidCapacityInput = 0;
|
||||
ovrSpaceContainer.uuidCountOutput = 0;
|
||||
ovrSpaceContainer.uuids = nullptr;
|
||||
ovrpResult result = FOculusXRHMDModule::GetPluginWrapper().GetSpaceContainer(&AnchorHandle, &ovrSpaceContainer);
|
||||
if (OVRP_FAILURE(result))
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("Failed to get space container %d"), result);
|
||||
return OculusXRAnchors::GetResultFromOVRResult(result);
|
||||
}
|
||||
|
||||
// Retrieve the actual array of UUIDs
|
||||
ovrUuidArray.SetNum(ovrSpaceContainer.uuidCountOutput);
|
||||
ovrSpaceContainer.uuidCapacityInput = ovrSpaceContainer.uuidCountOutput;
|
||||
ovrSpaceContainer.uuids = ovrUuidArray.GetData();
|
||||
|
||||
result = FOculusXRHMDModule::GetPluginWrapper().GetSpaceContainer(&AnchorHandle, &ovrSpaceContainer);
|
||||
if (OVRP_FAILURE(result))
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("Failed to get space container %d"), result);
|
||||
return OculusXRAnchors::GetResultFromOVRResult(result);
|
||||
}
|
||||
|
||||
// Write out the remaining UUIDs
|
||||
OutUUIDs.Reserve(ovrUuidArray.Num());
|
||||
for (auto& it : ovrUuidArray)
|
||||
{
|
||||
OutUUIDs.Add(FOculusXRUUID(it.data));
|
||||
}
|
||||
|
||||
return EOculusXRAnchorResult::Success;
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorFunctionsOVR::SaveAnchor(uint64 AnchorHandle,
|
||||
EOculusXRSpaceStorageLocation StorageLocation,
|
||||
EOculusXRSpaceStoragePersistenceMode StoragePersistenceMode, uint64& OutRequestId)
|
||||
{
|
||||
ovrpSpaceStorageLocation OvrpStorageLocation = ovrpSpaceStorageLocation_Local;
|
||||
switch (StorageLocation)
|
||||
{
|
||||
case EOculusXRSpaceStorageLocation::Invalid:
|
||||
OvrpStorageLocation = ovrpSpaceStorageLocation_Invalid;
|
||||
break;
|
||||
case EOculusXRSpaceStorageLocation::Local:
|
||||
OvrpStorageLocation = ovrpSpaceStorageLocation_Local;
|
||||
break;
|
||||
case EOculusXRSpaceStorageLocation::Cloud:
|
||||
OvrpStorageLocation = ovrpSpaceStorageLocation_Cloud;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ovrpSpaceStoragePersistenceMode OvrpStoragePersistenceMode = ovrpSpaceStoragePersistenceMode_Invalid;
|
||||
switch (StoragePersistenceMode)
|
||||
{
|
||||
case EOculusXRSpaceStoragePersistenceMode::Invalid:
|
||||
OvrpStoragePersistenceMode = ovrpSpaceStoragePersistenceMode_Invalid;
|
||||
break;
|
||||
case EOculusXRSpaceStoragePersistenceMode::Indefinite:
|
||||
OvrpStoragePersistenceMode = ovrpSpaceStoragePersistenceMode_Indefinite;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
const ovrpResult Result = FOculusXRHMDModule::GetPluginWrapper().SaveSpace(&AnchorHandle, OvrpStorageLocation, OvrpStoragePersistenceMode, &OutRequestId);
|
||||
|
||||
UE_LOG(LogOculusXRAnchors, Verbose, TEXT("Saving anchor with, ID: %llu -- Location: %d -- Persistence: %d -- OutID: %llu"), AnchorHandle, OvrpStorageLocation, OvrpStoragePersistenceMode, OutRequestId);
|
||||
|
||||
if (OVRP_FAILURE(Result))
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("FOculusXRHMD::SaveAnchor failed with, ID: %llu -- Location: %d -- Persistence: %d"), AnchorHandle, OvrpStorageLocation, OvrpStoragePersistenceMode);
|
||||
}
|
||||
|
||||
return OculusXRAnchors::GetResultFromOVRResult(Result);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorFunctionsOVR::SaveAnchorList(const TArray<uint64>& AnchorHandles, EOculusXRSpaceStorageLocation StorageLocation, uint64& OutRequestId)
|
||||
{
|
||||
ovrpSpaceStorageLocation OvrpStorageLocation = ovrpSpaceStorageLocation_Local;
|
||||
switch (StorageLocation)
|
||||
{
|
||||
case EOculusXRSpaceStorageLocation::Invalid:
|
||||
OvrpStorageLocation = ovrpSpaceStorageLocation_Invalid;
|
||||
break;
|
||||
case EOculusXRSpaceStorageLocation::Local:
|
||||
OvrpStorageLocation = ovrpSpaceStorageLocation_Local;
|
||||
break;
|
||||
case EOculusXRSpaceStorageLocation::Cloud:
|
||||
OvrpStorageLocation = ovrpSpaceStorageLocation_Cloud;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
const ovrpResult Result = FOculusXRHMDModule::GetPluginWrapper().SaveSpaceList(AnchorHandles.GetData(), AnchorHandles.Num(), OvrpStorageLocation, &OutRequestId);
|
||||
|
||||
UE_LOG(LogOculusXRAnchors, Verbose, TEXT("Saving space list: Location: %d -- OutID: %llu"), OvrpStorageLocation, OutRequestId);
|
||||
for (auto& it : AnchorHandles)
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Verbose, TEXT("\tSpaceID: %llu"), it);
|
||||
}
|
||||
|
||||
if (OVRP_FAILURE(Result))
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("SaveSpaceList failed -- Result: %d"), Result);
|
||||
}
|
||||
|
||||
return OculusXRAnchors::GetResultFromOVRResult(Result);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorFunctionsOVR::SaveAnchors(const TArray<uint64>& AnchorHandles, uint64& OutRequestId)
|
||||
{
|
||||
if (AnchorHandles.Num() == 0)
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("FOculusXRAnchorFunctionsOVR::SaveAnchors has empty handle array"));
|
||||
}
|
||||
|
||||
const ovrpResult Result = FOculusXRHMDModule::GetPluginWrapper().SaveSpaces(AnchorHandles.Num(), AnchorHandles.GetData(), &OutRequestId);
|
||||
|
||||
if (!OVRP_SUCCESS(Result))
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Error, TEXT("FOculusXRAnchorFunctionsOVR::SaveAnchors failed, result: %d"), Result);
|
||||
}
|
||||
|
||||
return OculusXRAnchors::GetResultFromOVRResult(Result);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorFunctionsOVR::DiscoverAnchors(const FOculusXRSpaceDiscoveryInfo& DiscoveryInfo, uint64& OutRequestId)
|
||||
{
|
||||
uint32 FiltersCount = (uint32)DiscoveryInfo.Filters.Num();
|
||||
ovrpSpaceDiscoveryInfo OvrDiscoveryInfo = {};
|
||||
OvrDiscoveryInfo.FilterCount = FiltersCount;
|
||||
|
||||
UE_LOG(LogOculusXRAnchors, Display, TEXT("Staring discovery with %d filter(s)"), FiltersCount);
|
||||
|
||||
TArray<const ovrpSpaceDiscoveryFilterHeader*> filters;
|
||||
filters.SetNumZeroed(FiltersCount);
|
||||
|
||||
for (uint32 i = 0; i < FiltersCount; ++i)
|
||||
{
|
||||
ensure(DiscoveryInfo.Filters[i] != nullptr);
|
||||
filters[i] = DiscoveryInfo.Filters[i]->GenerateOVRPFilter();
|
||||
}
|
||||
|
||||
OvrDiscoveryInfo.Filters = filters.GetData();
|
||||
const ovrpResult Result = FOculusXRHMDModule::GetPluginWrapper().DiscoverSpaces(&OvrDiscoveryInfo, &OutRequestId);
|
||||
|
||||
if (!OVRP_SUCCESS(Result))
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Error, TEXT("FOculusXRAnchorFunctionsOVR::DiscoverAnchors failed -- Result: %d"), Result);
|
||||
}
|
||||
|
||||
return OculusXRAnchors::GetResultFromOVRResult(Result);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorFunctionsOVR::QueryAnchors(const FOculusXRSpaceQueryInfo& QueryInfo, uint64& OutRequestId)
|
||||
{
|
||||
ovrpResult QuerySpacesResult = ovrpFailure;
|
||||
|
||||
ovrpSpaceQueryInfo2 ovrQueryInfo = ToOvrpSpaceQuery(QueryInfo);
|
||||
QuerySpacesResult = FOculusXRHMDModule::GetPluginWrapper().QuerySpaces2(&ovrQueryInfo, &OutRequestId);
|
||||
|
||||
UE_LOG(LogOculusXRAnchors, Verbose, TEXT("Query Spaces\n ovrpSpaceQueryInfo:\n\tQueryType: %d\n\tMaxQuerySpaces: %d\n\tTimeout: %f\n\tLocation: %d\n\tActionType: %d\n\tFilterType: %d\n\n\tRequest ID: %llu"),
|
||||
ovrQueryInfo.queryType, ovrQueryInfo.maxQuerySpaces, (float)ovrQueryInfo.timeout, ovrQueryInfo.location, ovrQueryInfo.actionType, ovrQueryInfo.filterType, OutRequestId);
|
||||
|
||||
if (QueryInfo.FilterType == EOculusXRSpaceQueryFilterType::FilterByIds)
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Verbose, TEXT("Query contains %d UUIDs"), QueryInfo.IDFilter.Num());
|
||||
for (auto& it : QueryInfo.IDFilter)
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Verbose, TEXT("UUID: %s"), *it.ToString());
|
||||
}
|
||||
}
|
||||
else if (QueryInfo.FilterType == EOculusXRSpaceQueryFilterType::FilterByComponentType)
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Verbose, TEXT("Query contains %d Component Types"), QueryInfo.ComponentFilter.Num());
|
||||
for (auto& it : QueryInfo.ComponentFilter)
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Verbose, TEXT("ComponentType: %s"), *UEnum::GetValueAsString(it));
|
||||
}
|
||||
}
|
||||
else if (QueryInfo.FilterType == EOculusXRSpaceQueryFilterType::FilterByGroup)
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Verbose, TEXT("Query contains group filter - UUID: %s"), *QueryInfo.GroupUUIDFilter.ToString());
|
||||
}
|
||||
|
||||
return OculusXRAnchors::GetResultFromOVRResult(QuerySpacesResult);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorFunctionsOVR::ShareAnchors(const TArray<uint64>& AchorHandles, const TArray<uint64>& UserIds, uint64& OutRequestId)
|
||||
{
|
||||
TArray<const char*> stringStorage;
|
||||
TArray<ovrpUser> OvrpUsers;
|
||||
for (const auto& UserId : UserIds)
|
||||
{
|
||||
ovrpUser OvrUser;
|
||||
ovrpResult Result = FOculusXRHMDModule::GetPluginWrapper().CreateSpaceUser(&UserId, &OvrUser);
|
||||
if (OVRP_FAILURE(Result))
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("Failed to create space user from ID - %llu"), UserId);
|
||||
continue;
|
||||
}
|
||||
|
||||
OvrpUsers.Add(OvrUser);
|
||||
}
|
||||
|
||||
const ovrpResult ShareSpacesResult = FOculusXRHMDModule::GetPluginWrapper().ShareSpaces(AchorHandles.GetData(), AchorHandles.Num(), OvrpUsers.GetData(), OvrpUsers.Num(), &OutRequestId);
|
||||
|
||||
UE_LOG(LogOculusXRAnchors, Verbose, TEXT("Sharing space list -- OutID: %llu"), OutRequestId);
|
||||
for (auto& User : OvrpUsers)
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Verbose, TEXT("\tOvrpUser: %llu"), User);
|
||||
ovrpResult Result = FOculusXRHMDModule::GetPluginWrapper().DestroySpaceUser(&User);
|
||||
if (OVRP_FAILURE(Result))
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Verbose, TEXT("Failed to destroy space user: %llu"), User);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& it : AchorHandles)
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Verbose, TEXT("\tSpaceID: %llu"), it);
|
||||
}
|
||||
|
||||
return OculusXRAnchors::GetResultFromOVRResult(ShareSpacesResult);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorFunctionsOVR::ShareAnchors(const TArray<uint64>& AnchorHandles, const TArray<FOculusXRUUID>& Groups, uint64& OutRequestId)
|
||||
{
|
||||
TArray<ovrpUuid> groupUuids;
|
||||
groupUuids.Reserve(Groups.Num());
|
||||
for (auto& it : Groups)
|
||||
{
|
||||
ovrpUuid uuid;
|
||||
FMemory::Memcpy(uuid.data, it.UUIDBytes);
|
||||
groupUuids.Add(uuid);
|
||||
}
|
||||
|
||||
TSharedPtr<ovrpShareSpacesGroupRecipientInfo> groupRecipientInfo = MakeShared<ovrpShareSpacesGroupRecipientInfo>();
|
||||
groupRecipientInfo->GroupCount = groupUuids.Num();
|
||||
groupRecipientInfo->GroupUuids = groupUuids.GetData();
|
||||
|
||||
ovrpShareSpacesInfo shareInfo;
|
||||
shareInfo.SpaceCount = AnchorHandles.Num();
|
||||
shareInfo.Spaces = (ovrpSpace*)AnchorHandles.GetData();
|
||||
shareInfo.RecipientType = ovrpShareSpacesRecipientType_Group;
|
||||
shareInfo.RecipientInfo = groupRecipientInfo.Get();
|
||||
|
||||
ovrpResult result = FOculusXRHMDModule::GetPluginWrapper().ShareSpaces2(&shareInfo, &OutRequestId);
|
||||
|
||||
return OculusXRAnchors::GetResultFromOVRResult(result);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorFunctionsOVR::EraseAnchor(uint64 AnchorHandle,
|
||||
EOculusXRSpaceStorageLocation StorageLocation, uint64& OutRequestId)
|
||||
{
|
||||
ovrpSpaceStorageLocation ovrpStorageLocation = ovrpSpaceStorageLocation_Local;
|
||||
switch (StorageLocation)
|
||||
{
|
||||
case EOculusXRSpaceStorageLocation::Invalid:
|
||||
ovrpStorageLocation = ovrpSpaceStorageLocation_Invalid;
|
||||
break;
|
||||
case EOculusXRSpaceStorageLocation::Local:
|
||||
ovrpStorageLocation = ovrpSpaceStorageLocation_Local;
|
||||
break;
|
||||
case EOculusXRSpaceStorageLocation::Cloud:
|
||||
ovrpStorageLocation = ovrpSpaceStorageLocation_Cloud;
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
|
||||
ovrpUInt64 OvrpOutRequestId = 0;
|
||||
const ovrpResult Result = FOculusXRHMDModule::GetPluginWrapper().EraseSpace(&AnchorHandle, ovrpStorageLocation, &OvrpOutRequestId);
|
||||
memcpy(&OutRequestId, &OvrpOutRequestId, sizeof(uint64));
|
||||
|
||||
UE_LOG(LogOculusXRAnchors, Log, TEXT("Erasing anchor -- Handle: %llu -- Location: %d -- OutID: %llu"), AnchorHandle, ovrpStorageLocation, OvrpOutRequestId);
|
||||
|
||||
return OculusXRAnchors::GetResultFromOVRResult(Result);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorFunctionsOVR::EraseAnchors(const TArray<FOculusXRUInt64>& AnchorHandles, const TArray<FOculusXRUUID>& UUIDs, uint64& OutRequestId)
|
||||
{
|
||||
if (AnchorHandles.IsEmpty() && UUIDs.IsEmpty())
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("FOculusXRAnchorFunctionsOVR::EraseAnchors - You cannot have an empty handle and uuid array. At least one array must have elements."));
|
||||
return EOculusXRAnchorResult::Failure_InvalidParameter;
|
||||
}
|
||||
|
||||
TArray<ovrpSpace> ovrpHandles;
|
||||
for (auto& handle : AnchorHandles)
|
||||
{
|
||||
ovrpHandles.Add(handle.GetValue());
|
||||
}
|
||||
|
||||
TArray<ovrpUuid> ovrpUUIDs;
|
||||
for (auto& id : UUIDs)
|
||||
{
|
||||
ovrpUuid OvrUuid;
|
||||
FMemory::Memcpy(OvrUuid.data, id.UUIDBytes);
|
||||
ovrpUUIDs.Add(OvrUuid);
|
||||
}
|
||||
|
||||
const ovrpResult Result = FOculusXRHMDModule::GetPluginWrapper().EraseSpaces(ovrpHandles.Num(), ovrpHandles.GetData(), ovrpUUIDs.Num(), ovrpUUIDs.GetData(), &OutRequestId);
|
||||
|
||||
if (!OVRP_SUCCESS(Result))
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Error, TEXT("FOculusXRAnchorFunctionsOVR::EraseAnchors failed -- Result: %d"), Result);
|
||||
}
|
||||
|
||||
return OculusXRAnchors::GetResultFromOVRResult(Result);
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "OculusXRAnchorFunctions.h"
|
||||
|
||||
class OCULUSXRANCHORS_API FOculusXRAnchorFunctionsOVR : public IOculusXRAnchorFunctions
|
||||
{
|
||||
public:
|
||||
virtual EOculusXRAnchorResult::Type CreateAnchor(const FTransform& InTransform, uint64& OutRequestId, const FTransform& CameraTransform) override;
|
||||
virtual EOculusXRAnchorResult::Type DestroyAnchor(uint64 AnchorHandle) override;
|
||||
|
||||
virtual EOculusXRAnchorResult::Type TryGetAnchorTransform(uint64 AnchorHandle, FTransform& OutTransform, FOculusXRAnchorLocationFlags& OutLocationFlags, EOculusXRAnchorSpace Space) override;
|
||||
virtual EOculusXRAnchorResult::Type SetAnchorComponentStatus(uint64 AnchorHandle, EOculusXRSpaceComponentType ComponentType, bool Enable, float Timeout, uint64& OutRequestId) override;
|
||||
virtual EOculusXRAnchorResult::Type GetAnchorComponentStatus(uint64 AnchorHandle, EOculusXRSpaceComponentType ComponentType, bool& OutEnabled, bool& OutChangePending) override;
|
||||
virtual EOculusXRAnchorResult::Type GetSupportedAnchorComponents(uint64 AnchorHandle, TArray<EOculusXRSpaceComponentType>& OutSupportedTypes) override;
|
||||
virtual EOculusXRAnchorResult::Type GetAnchorContainerUUIDs(uint64 AnchorHandle, TArray<FOculusXRUUID>& OutUUIDs) override;
|
||||
|
||||
virtual EOculusXRAnchorResult::Type SaveAnchor(uint64 AnchorHandle, EOculusXRSpaceStorageLocation StorageLocation, EOculusXRSpaceStoragePersistenceMode StoragePersistenceMode, uint64& OutRequestId) override;
|
||||
virtual EOculusXRAnchorResult::Type SaveAnchorList(const TArray<uint64>& AnchorHandles, EOculusXRSpaceStorageLocation StorageLocation, uint64& OutRequestId) override;
|
||||
virtual EOculusXRAnchorResult::Type SaveAnchors(const TArray<uint64>& AnchorHandles, uint64& OutRequestId) override;
|
||||
|
||||
virtual EOculusXRAnchorResult::Type DiscoverAnchors(const FOculusXRSpaceDiscoveryInfo& DiscoveryInfo, uint64& OutRequestId) override;
|
||||
virtual EOculusXRAnchorResult::Type QueryAnchors(const FOculusXRSpaceQueryInfo& QueryInfo, uint64& OutRequestId) override;
|
||||
virtual EOculusXRAnchorResult::Type ShareAnchors(const TArray<uint64>& AnchorHandles, const TArray<uint64>& UserIds, uint64& OutRequestId) override;
|
||||
virtual EOculusXRAnchorResult::Type ShareAnchors(const TArray<uint64>& AnchorHandles, const TArray<FOculusXRUUID>& Groups, uint64& OutRequestId) override;
|
||||
|
||||
virtual EOculusXRAnchorResult::Type EraseAnchor(uint64 AnchorHandle, EOculusXRSpaceStorageLocation StorageLocation, uint64& OutRequestId) override;
|
||||
virtual EOculusXRAnchorResult::Type EraseAnchors(const TArray<FOculusXRUInt64>& AnchorHandles, const TArray<FOculusXRUUID>& UUIDs, uint64& OutRequestId) override;
|
||||
};
|
||||
@@ -0,0 +1,108 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
#include "OculusXRAnchorFunctionsOpenXR.h"
|
||||
#include "OculusXRHMD.h"
|
||||
#include "OculusXRAnchorsModule.h"
|
||||
#include "OculusXRAnchorDelegates.h"
|
||||
#include "OculusXRAnchorBPFunctionLibrary.h"
|
||||
#include "OculusXRAnchorTypesPrivate.h"
|
||||
#include "OculusXRAnchorsUtil.h"
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorFunctionsOpenXR::CreateAnchor(const FTransform& InTransform, uint64& OutRequestId, const FTransform& CameraTransform)
|
||||
{
|
||||
auto result = FOculusXRAnchorsModule::Get().GetXrAnchors()->CreateSpatialAnchor(InTransform, OutRequestId, CameraTransform);
|
||||
return OculusXRAnchors::GetResultFromXrResult(result);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorFunctionsOpenXR::DestroyAnchor(uint64 AnchorHandle)
|
||||
{
|
||||
auto result = FOculusXRAnchorsModule::Get().GetXrAnchors()->DestroySpatialAnchor(AnchorHandle);
|
||||
return OculusXRAnchors::GetResultFromXrResult(result);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorFunctionsOpenXR::TryGetAnchorTransform(uint64 AnchorHandle, FTransform& OutTransform, FOculusXRAnchorLocationFlags& OutLocationFlags, EOculusXRAnchorSpace Space)
|
||||
{
|
||||
auto result = FOculusXRAnchorsModule::Get().GetXrAnchors()->TryGetAnchorTransform(AnchorHandle, OutTransform, OutLocationFlags, Space);
|
||||
return OculusXRAnchors::GetResultFromXrResult(result);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorFunctionsOpenXR::SetAnchorComponentStatus(uint64 AnchorHandle, EOculusXRSpaceComponentType ComponentType, bool Enable, float Timeout, uint64& OutRequestId)
|
||||
{
|
||||
auto result = FOculusXRAnchorsModule::Get().GetXrAnchors()->SetAnchorComponentStatus(AnchorHandle, ComponentType, Enable, Timeout, OutRequestId);
|
||||
return OculusXRAnchors::GetResultFromXrResult(result);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorFunctionsOpenXR::GetAnchorComponentStatus(uint64 AnchorHandle, EOculusXRSpaceComponentType ComponentType, bool& OutEnabled, bool& OutChangePending)
|
||||
{
|
||||
auto result = FOculusXRAnchorsModule::Get().GetXrAnchors()->GetAnchorComponentStatus(AnchorHandle, ComponentType, OutEnabled, OutChangePending);
|
||||
return OculusXRAnchors::GetResultFromXrResult(result);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorFunctionsOpenXR::GetSupportedAnchorComponents(uint64 AnchorHandle, TArray<EOculusXRSpaceComponentType>& OutSupportedTypes)
|
||||
{
|
||||
auto result = FOculusXRAnchorsModule::Get().GetXrAnchors()->GetSupportedAnchorComponents(AnchorHandle, OutSupportedTypes);
|
||||
return OculusXRAnchors::GetResultFromXrResult(result);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorFunctionsOpenXR::GetAnchorContainerUUIDs(uint64 AnchorHandle, TArray<FOculusXRUUID>& OutUUIDs)
|
||||
{
|
||||
auto result = FOculusXRAnchorsModule::Get().GetXrAnchors()->GetAnchorContainerUUIDs(AnchorHandle, OutUUIDs);
|
||||
return OculusXRAnchors::GetResultFromXrResult(result);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorFunctionsOpenXR::SaveAnchor(uint64 AnchorHandle,
|
||||
EOculusXRSpaceStorageLocation StorageLocation,
|
||||
EOculusXRSpaceStoragePersistenceMode StoragePersistenceMode, uint64& OutRequestId)
|
||||
{
|
||||
auto result = FOculusXRAnchorsModule::Get().GetXrAnchors()->SaveAnchor(AnchorHandle, StorageLocation, StoragePersistenceMode, OutRequestId);
|
||||
return OculusXRAnchors::GetResultFromXrResult(result);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorFunctionsOpenXR::SaveAnchorList(const TArray<uint64>& AnchorHandles, EOculusXRSpaceStorageLocation StorageLocation, uint64& OutRequestId)
|
||||
{
|
||||
auto result = FOculusXRAnchorsModule::Get().GetXrAnchors()->SaveAnchorList(AnchorHandles, StorageLocation, OutRequestId);
|
||||
return OculusXRAnchors::GetResultFromXrResult(result);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorFunctionsOpenXR::SaveAnchors(const TArray<uint64>& AnchorHandles, uint64& OutRequestId)
|
||||
{
|
||||
auto result = FOculusXRAnchorsModule::Get().GetXrAnchors()->SaveAnchors(AnchorHandles, OutRequestId);
|
||||
return OculusXRAnchors::GetResultFromXrResult(result);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorFunctionsOpenXR::DiscoverAnchors(const FOculusXRSpaceDiscoveryInfo& DiscoveryInfo, uint64& OutRequestId)
|
||||
{
|
||||
auto result = FOculusXRAnchorsModule::Get().GetXrAnchors()->DiscoverAnchors(DiscoveryInfo, OutRequestId);
|
||||
return OculusXRAnchors::GetResultFromXrResult(result);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorFunctionsOpenXR::QueryAnchors(const FOculusXRSpaceQueryInfo& QueryInfo, uint64& OutRequestId)
|
||||
{
|
||||
auto result = FOculusXRAnchorsModule::Get().GetXrAnchors()->QueryAnchors(QueryInfo, OutRequestId);
|
||||
return OculusXRAnchors::GetResultFromXrResult(result);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorFunctionsOpenXR::ShareAnchors(const TArray<uint64>& AnchorHandles, const TArray<uint64>& UserIds, uint64& OutRequestId)
|
||||
{
|
||||
auto result = FOculusXRAnchorsModule::Get().GetXrAnchors()->ShareAnchors(AnchorHandles, UserIds, OutRequestId);
|
||||
return OculusXRAnchors::GetResultFromXrResult(result);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorFunctionsOpenXR::ShareAnchors(const TArray<uint64>& AnchorHandles, const TArray<FOculusXRUUID>& Groups, uint64& OutRequestId)
|
||||
{
|
||||
auto result = FOculusXRAnchorsModule::Get().GetXrAnchors()->ShareAnchorsWithGroups(AnchorHandles, Groups, OutRequestId);
|
||||
return OculusXRAnchors::GetResultFromXrResult(result);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorFunctionsOpenXR::EraseAnchor(uint64 AnchorHandle,
|
||||
EOculusXRSpaceStorageLocation StorageLocation, uint64& OutRequestId)
|
||||
{
|
||||
auto result = FOculusXRAnchorsModule::Get().GetXrAnchors()->EraseAnchor(AnchorHandle, StorageLocation, OutRequestId);
|
||||
return OculusXRAnchors::GetResultFromXrResult(result);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorFunctionsOpenXR::EraseAnchors(const TArray<FOculusXRUInt64>& AnchorHandles, const TArray<FOculusXRUUID>& UUIDs, uint64& OutRequestId)
|
||||
{
|
||||
auto result = FOculusXRAnchorsModule::Get().GetXrAnchors()->EraseAnchors(AnchorHandles, UUIDs, OutRequestId);
|
||||
return OculusXRAnchors::GetResultFromXrResult(result);
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "OculusXRAnchorFunctions.h"
|
||||
|
||||
class OCULUSXRANCHORS_API FOculusXRAnchorFunctionsOpenXR : public IOculusXRAnchorFunctions
|
||||
{
|
||||
public:
|
||||
virtual EOculusXRAnchorResult::Type CreateAnchor(const FTransform& InTransform, uint64& OutRequestId, const FTransform& CameraTransform) override;
|
||||
virtual EOculusXRAnchorResult::Type DestroyAnchor(uint64 AnchorHandle) override;
|
||||
|
||||
virtual EOculusXRAnchorResult::Type TryGetAnchorTransform(uint64 AnchorHandle, FTransform& OutTransform, FOculusXRAnchorLocationFlags& OutLocationFlags, EOculusXRAnchorSpace Space) override;
|
||||
virtual EOculusXRAnchorResult::Type SetAnchorComponentStatus(uint64 AnchorHandle, EOculusXRSpaceComponentType ComponentType, bool Enable, float Timeout, uint64& OutRequestId) override;
|
||||
virtual EOculusXRAnchorResult::Type GetAnchorComponentStatus(uint64 AnchorHandle, EOculusXRSpaceComponentType ComponentType, bool& OutEnabled, bool& OutChangePending) override;
|
||||
virtual EOculusXRAnchorResult::Type GetSupportedAnchorComponents(uint64 AnchorHandle, TArray<EOculusXRSpaceComponentType>& OutSupportedTypes) override;
|
||||
virtual EOculusXRAnchorResult::Type GetAnchorContainerUUIDs(uint64 AnchorHandle, TArray<FOculusXRUUID>& OutUUIDs) override;
|
||||
|
||||
virtual EOculusXRAnchorResult::Type SaveAnchor(uint64 AnchorHandle, EOculusXRSpaceStorageLocation StorageLocation, EOculusXRSpaceStoragePersistenceMode StoragePersistenceMode, uint64& OutRequestId) override;
|
||||
virtual EOculusXRAnchorResult::Type SaveAnchorList(const TArray<uint64>& AnchorHandles, EOculusXRSpaceStorageLocation StorageLocation, uint64& OutRequestId) override;
|
||||
virtual EOculusXRAnchorResult::Type SaveAnchors(const TArray<uint64>& AnchorHandles, uint64& OutRequestId) override;
|
||||
|
||||
virtual EOculusXRAnchorResult::Type DiscoverAnchors(const FOculusXRSpaceDiscoveryInfo& DiscoveryInfo, uint64& OutRequestId) override;
|
||||
virtual EOculusXRAnchorResult::Type QueryAnchors(const FOculusXRSpaceQueryInfo& QueryInfo, uint64& OutRequestId) override;
|
||||
virtual EOculusXRAnchorResult::Type ShareAnchors(const TArray<uint64>& AnchorHandles, const TArray<uint64>& UserIds, uint64& OutRequestId) override;
|
||||
virtual EOculusXRAnchorResult::Type ShareAnchors(const TArray<uint64>& AnchorHandles, const TArray<FOculusXRUUID>& Groups, uint64& OutRequestId) override;
|
||||
|
||||
virtual EOculusXRAnchorResult::Type EraseAnchor(uint64 AnchorHandle, EOculusXRSpaceStorageLocation StorageLocation, uint64& OutRequestId) override;
|
||||
virtual EOculusXRAnchorResult::Type EraseAnchors(const TArray<FOculusXRUInt64>& AnchorHandles, const TArray<FOculusXRUUID>& UUIDs, uint64& OutRequestId) override;
|
||||
};
|
||||
@@ -0,0 +1,846 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
#include "OculusXRAnchorLatentActions.h"
|
||||
#include "OculusXRAnchorsPrivate.h"
|
||||
#include "OculusXRHMD.h"
|
||||
#include "OculusXRAnchorBPFunctionLibrary.h"
|
||||
#include "OculusXRAnchorDelegates.h"
|
||||
#include "OculusXRAnchorsModule.h"
|
||||
|
||||
//
|
||||
// Create Spatial Anchor
|
||||
//
|
||||
void UOculusXRAsyncAction_CreateSpatialAnchor::Activate()
|
||||
{
|
||||
if (!IsValid(TargetActor))
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("Invalid Target Actor passed to CreateSpatialAnchor latent action."));
|
||||
|
||||
Failure.Broadcast(EOculusXRAnchorResult::Failure);
|
||||
return;
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type Result;
|
||||
bool bStartedAsync = OculusXRAnchors::FOculusXRAnchors::CreateSpatialAnchor(
|
||||
AnchorTransform,
|
||||
TargetActor,
|
||||
FOculusXRSpatialAnchorCreateDelegate::CreateUObject(this, &UOculusXRAsyncAction_CreateSpatialAnchor::HandleCreateComplete),
|
||||
Result);
|
||||
|
||||
if (!bStartedAsync)
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("Failed to start async OVR Plugin call for CreateSpatialAnchor latent action."));
|
||||
Failure.Broadcast(Result);
|
||||
}
|
||||
}
|
||||
|
||||
UOculusXRAsyncAction_CreateSpatialAnchor* UOculusXRAsyncAction_CreateSpatialAnchor::OculusXRAsyncCreateSpatialAnchor(AActor* TargetActor, const FTransform& AnchorTransform)
|
||||
{
|
||||
UOculusXRAsyncAction_CreateSpatialAnchor* Action = NewObject<UOculusXRAsyncAction_CreateSpatialAnchor>();
|
||||
Action->TargetActor = TargetActor;
|
||||
Action->AnchorTransform = AnchorTransform;
|
||||
|
||||
if (IsValid(TargetActor))
|
||||
{
|
||||
Action->RegisterWithGameInstance(TargetActor->GetWorld());
|
||||
}
|
||||
else
|
||||
{
|
||||
Action->RegisterWithGameInstance(GWorld);
|
||||
}
|
||||
|
||||
return Action;
|
||||
}
|
||||
|
||||
void UOculusXRAsyncAction_CreateSpatialAnchor::HandleCreateComplete(EOculusXRAnchorResult::Type CreateResult, UOculusXRAnchorComponent* Anchor)
|
||||
{
|
||||
if (UOculusXRAnchorBPFunctionLibrary::IsAnchorResultSuccess(CreateResult))
|
||||
{
|
||||
Success.Broadcast(Anchor, CreateResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
Failure.Broadcast(CreateResult);
|
||||
}
|
||||
|
||||
SetReadyToDestroy();
|
||||
}
|
||||
|
||||
//
|
||||
// Erase Space
|
||||
//
|
||||
void UOculusXRAsyncAction_EraseAnchor::Activate()
|
||||
{
|
||||
if (!IsValid(TargetActor))
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("Invalid Target Actor passed to EraseSpace latent action."));
|
||||
|
||||
Failure.Broadcast(EOculusXRAnchorResult::Failure);
|
||||
return;
|
||||
}
|
||||
|
||||
UOculusXRAnchorComponent* AnchorComponent = TargetActor->FindComponentByClass<UOculusXRAnchorComponent>();
|
||||
if (AnchorComponent == nullptr)
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("No anchor on actor in EraseSpace latent action."));
|
||||
|
||||
Failure.Broadcast(EOculusXRAnchorResult::Failure);
|
||||
return;
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type Result;
|
||||
bool bStartedAsync = OculusXRAnchors::FOculusXRAnchors::EraseAnchor(
|
||||
AnchorComponent,
|
||||
FOculusXRAnchorEraseDelegate::CreateUObject(this, &UOculusXRAsyncAction_EraseAnchor::HandleEraseAnchorComplete),
|
||||
Result);
|
||||
|
||||
if (!bStartedAsync)
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("Failed to start async OVR Plugin call for EraseSpace latent action."));
|
||||
|
||||
Failure.Broadcast(Result);
|
||||
}
|
||||
}
|
||||
|
||||
UOculusXRAsyncAction_EraseAnchor* UOculusXRAsyncAction_EraseAnchor::OculusXRAsyncEraseAnchor(AActor* TargetActor)
|
||||
{
|
||||
UOculusXRAsyncAction_EraseAnchor* Action = NewObject<UOculusXRAsyncAction_EraseAnchor>();
|
||||
Action->TargetActor = TargetActor;
|
||||
|
||||
if (IsValid(TargetActor))
|
||||
{
|
||||
Action->RegisterWithGameInstance(TargetActor->GetWorld());
|
||||
}
|
||||
else
|
||||
{
|
||||
Action->RegisterWithGameInstance(GWorld);
|
||||
}
|
||||
|
||||
return Action;
|
||||
}
|
||||
|
||||
void UOculusXRAsyncAction_EraseAnchor::HandleEraseAnchorComplete(EOculusXRAnchorResult::Type EraseResult, FOculusXRUUID UUID)
|
||||
{
|
||||
if (UOculusXRAnchorBPFunctionLibrary::IsAnchorResultSuccess(EraseResult))
|
||||
{
|
||||
Success.Broadcast(TargetActor, UUID, EraseResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
Failure.Broadcast(EraseResult);
|
||||
}
|
||||
|
||||
SetReadyToDestroy();
|
||||
}
|
||||
|
||||
//
|
||||
// Save Space
|
||||
//
|
||||
void UOculusXRAsyncAction_SaveAnchor::Activate()
|
||||
{
|
||||
if (!IsValid(TargetActor))
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("Invalid Target Actor passed to SaveSpace latent action."));
|
||||
|
||||
Failure.Broadcast(EOculusXRAnchorResult::Failure);
|
||||
return;
|
||||
}
|
||||
|
||||
UOculusXRAnchorComponent* AnchorComponent = TargetActor->FindComponentByClass<UOculusXRAnchorComponent>();
|
||||
if (AnchorComponent == nullptr)
|
||||
{
|
||||
Failure.Broadcast(EOculusXRAnchorResult::Failure);
|
||||
return;
|
||||
}
|
||||
|
||||
UE_LOG(LogOculusXRAnchors, Log, TEXT("Attempting to save anchor: %s to location %s"), IsValid(AnchorComponent) ? *AnchorComponent->GetName() : TEXT("INVALID ANCHOR"), *UEnum::GetValueAsString(StorageLocation));
|
||||
|
||||
EOculusXRAnchorResult::Type Result;
|
||||
bool bStartedAsync = OculusXRAnchors::FOculusXRAnchors::SaveAnchor(
|
||||
AnchorComponent,
|
||||
StorageLocation,
|
||||
FOculusXRAnchorSaveDelegate::CreateUObject(this, &UOculusXRAsyncAction_SaveAnchor::HandleSaveAnchorComplete),
|
||||
Result);
|
||||
|
||||
if (!bStartedAsync)
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("Failed to start async OVR Plugin call for SaveSpace latent action."));
|
||||
Failure.Broadcast(Result);
|
||||
}
|
||||
}
|
||||
|
||||
UOculusXRAsyncAction_SaveAnchor* UOculusXRAsyncAction_SaveAnchor::OculusXRAsyncSaveAnchor(AActor* TargetActor, EOculusXRSpaceStorageLocation StorageLocation)
|
||||
{
|
||||
UOculusXRAsyncAction_SaveAnchor* Action = NewObject<UOculusXRAsyncAction_SaveAnchor>();
|
||||
Action->TargetActor = TargetActor;
|
||||
Action->StorageLocation = StorageLocation;
|
||||
|
||||
if (IsValid(TargetActor))
|
||||
{
|
||||
Action->RegisterWithGameInstance(TargetActor->GetWorld());
|
||||
}
|
||||
else
|
||||
{
|
||||
Action->RegisterWithGameInstance(GWorld);
|
||||
}
|
||||
|
||||
return Action;
|
||||
}
|
||||
|
||||
void UOculusXRAsyncAction_SaveAnchor::HandleSaveAnchorComplete(EOculusXRAnchorResult::Type SaveResult, UOculusXRAnchorComponent* Anchor)
|
||||
{
|
||||
if (UOculusXRAnchorBPFunctionLibrary::IsAnchorResultSuccess(SaveResult))
|
||||
{
|
||||
Success.Broadcast(Anchor, SaveResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
Failure.Broadcast(SaveResult);
|
||||
}
|
||||
|
||||
SetReadyToDestroy();
|
||||
}
|
||||
|
||||
//
|
||||
// Save Anchor List
|
||||
//
|
||||
void UOculusXRAsyncAction_SaveAnchorList::Activate()
|
||||
{
|
||||
if (TargetAnchors.Num() == 0)
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("Empty Target Actor array passed to SaveSpaces latent action."));
|
||||
|
||||
Failure.Broadcast(EOculusXRAnchorResult::Failure);
|
||||
return;
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type Result;
|
||||
bool bStartedAsync = OculusXRAnchors::FOculusXRAnchors::SaveAnchorList(
|
||||
TargetAnchors,
|
||||
StorageLocation,
|
||||
FOculusXRAnchorSaveListDelegate::CreateUObject(this, &UOculusXRAsyncAction_SaveAnchorList::HandleSaveAnchorListComplete),
|
||||
Result);
|
||||
|
||||
if (!bStartedAsync)
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("Failed to start async OVR Plugin call for SaveSpaceList latent action."));
|
||||
|
||||
Failure.Broadcast(Result);
|
||||
}
|
||||
}
|
||||
|
||||
UOculusXRAsyncAction_SaveAnchorList* UOculusXRAsyncAction_SaveAnchorList::OculusXRAsyncSaveAnchorList(const TArray<AActor*>& TargetActors, EOculusXRSpaceStorageLocation StorageLocation)
|
||||
{
|
||||
UOculusXRAsyncAction_SaveAnchorList* Action = NewObject<UOculusXRAsyncAction_SaveAnchorList>();
|
||||
|
||||
auto ValidActorPtr = TargetActors.FindByPredicate([](AActor* Actor) { return IsValid(Actor); });
|
||||
|
||||
for (auto& it : TargetActors)
|
||||
{
|
||||
if (!IsValid(it))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
UOculusXRAnchorComponent* AnchorComponent = it->FindComponentByClass<UOculusXRAnchorComponent>();
|
||||
Action->TargetAnchors.Add(AnchorComponent);
|
||||
}
|
||||
|
||||
Action->StorageLocation = StorageLocation;
|
||||
|
||||
if (ValidActorPtr != nullptr)
|
||||
{
|
||||
Action->RegisterWithGameInstance(*ValidActorPtr);
|
||||
}
|
||||
|
||||
return Action;
|
||||
}
|
||||
|
||||
void UOculusXRAsyncAction_SaveAnchorList::HandleSaveAnchorListComplete(EOculusXRAnchorResult::Type SaveResult, const TArray<UOculusXRAnchorComponent*>& SavedSpaces)
|
||||
{
|
||||
if (UOculusXRAnchorBPFunctionLibrary::IsAnchorResultSuccess(SaveResult))
|
||||
{
|
||||
Success.Broadcast(SavedSpaces, SaveResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
Failure.Broadcast(SaveResult);
|
||||
}
|
||||
|
||||
SetReadyToDestroy();
|
||||
}
|
||||
|
||||
//
|
||||
// Query Spaces
|
||||
//
|
||||
void UOculusXRAsyncAction_QueryAnchors::Activate()
|
||||
{
|
||||
EOculusXRAnchorResult::Type Result;
|
||||
bool bStartedAsync = OculusXRAnchors::FOculusXRAnchors::QueryAnchorsAdvanced(
|
||||
QueryInfo,
|
||||
FOculusXRAnchorQueryDelegate::CreateUObject(this, &UOculusXRAsyncAction_QueryAnchors::HandleQueryAnchorsResults),
|
||||
Result);
|
||||
|
||||
if (!bStartedAsync)
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("Failed to start async OVR Plugin call for QuerySpaces latent action."));
|
||||
|
||||
Failure.Broadcast(Result);
|
||||
}
|
||||
}
|
||||
|
||||
UOculusXRAsyncAction_QueryAnchors* UOculusXRAsyncAction_QueryAnchors::OculusXRAsyncQueryAnchors(EOculusXRSpaceStorageLocation Location, const TArray<FOculusXRUUID>& UUIDs)
|
||||
{
|
||||
FOculusXRSpaceQueryInfo QueryInfo;
|
||||
QueryInfo.FilterType = EOculusXRSpaceQueryFilterType::FilterByIds;
|
||||
QueryInfo.IDFilter = UUIDs;
|
||||
QueryInfo.Location = Location;
|
||||
QueryInfo.MaxQuerySpaces = UUIDs.Num();
|
||||
|
||||
UOculusXRAsyncAction_QueryAnchors* Action = NewObject<UOculusXRAsyncAction_QueryAnchors>();
|
||||
Action->QueryInfo = QueryInfo;
|
||||
|
||||
return Action;
|
||||
}
|
||||
|
||||
UOculusXRAsyncAction_QueryAnchors* UOculusXRAsyncAction_QueryAnchors::OculusXRAsyncQueryAnchorsAdvanced(const FOculusXRSpaceQueryInfo& QueryInfo)
|
||||
{
|
||||
UOculusXRAsyncAction_QueryAnchors* Action = NewObject<UOculusXRAsyncAction_QueryAnchors>();
|
||||
Action->QueryInfo = QueryInfo;
|
||||
|
||||
return Action;
|
||||
}
|
||||
|
||||
void UOculusXRAsyncAction_QueryAnchors::HandleQueryAnchorsResults(EOculusXRAnchorResult::Type QueryResult, const TArray<FOculusXRSpaceQueryResult>& Results)
|
||||
{
|
||||
QueryResults = Results;
|
||||
|
||||
if (UOculusXRAnchorBPFunctionLibrary::IsAnchorResultSuccess(QueryResult))
|
||||
{
|
||||
Success.Broadcast(QueryResults, QueryResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
Failure.Broadcast(QueryResult);
|
||||
}
|
||||
|
||||
SetReadyToDestroy();
|
||||
}
|
||||
|
||||
//
|
||||
// Set Component Status with Anchor Actor
|
||||
//
|
||||
void UOculusXRAsyncAction_SetAnchorComponentStatus::Activate()
|
||||
{
|
||||
if (!IsValid(TargetActor))
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("Invalid Target Actor passed to SetComponentStatus latent action."));
|
||||
|
||||
Failure.Broadcast(EOculusXRAnchorResult::Failure);
|
||||
return;
|
||||
}
|
||||
|
||||
TargetAnchorComponent = TargetActor->FindComponentByClass<UOculusXRAnchorComponent>();
|
||||
if (TargetAnchorComponent == nullptr)
|
||||
{
|
||||
Failure.Broadcast(EOculusXRAnchorResult::Failure);
|
||||
return;
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type Result;
|
||||
bool bStartedAsync = OculusXRAnchors::FOculusXRAnchors::SetAnchorComponentStatus(
|
||||
TargetAnchorComponent,
|
||||
ComponentType,
|
||||
bEnabled,
|
||||
0,
|
||||
FOculusXRAnchorSetComponentStatusDelegate::CreateUObject(this, &UOculusXRAsyncAction_SetAnchorComponentStatus::HandleSetComponentStatusComplete),
|
||||
Result);
|
||||
|
||||
if (!bStartedAsync)
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("Failed to start async OVR Plugin call for SetComponentStatus latent action."));
|
||||
|
||||
Failure.Broadcast(Result);
|
||||
}
|
||||
}
|
||||
|
||||
UOculusXRAsyncAction_SetAnchorComponentStatus* UOculusXRAsyncAction_SetAnchorComponentStatus::OculusXRAsyncSetAnchorComponentStatus(AActor* TargetActor, EOculusXRSpaceComponentType ComponentType, bool bEnabled)
|
||||
{
|
||||
UOculusXRAsyncAction_SetAnchorComponentStatus* Action = NewObject<UOculusXRAsyncAction_SetAnchorComponentStatus>();
|
||||
Action->TargetActor = TargetActor;
|
||||
Action->ComponentType = ComponentType;
|
||||
Action->bEnabled = bEnabled;
|
||||
|
||||
if (IsValid(TargetActor))
|
||||
{
|
||||
Action->RegisterWithGameInstance(TargetActor->GetWorld());
|
||||
}
|
||||
else
|
||||
{
|
||||
Action->RegisterWithGameInstance(GWorld);
|
||||
}
|
||||
|
||||
return Action;
|
||||
}
|
||||
|
||||
void UOculusXRAsyncAction_SetAnchorComponentStatus::HandleSetComponentStatusComplete(EOculusXRAnchorResult::Type SetStatusResult, uint64 AnchorHandle, EOculusXRSpaceComponentType SpaceComponentType, bool bResultEnabled)
|
||||
{
|
||||
if (UOculusXRAnchorBPFunctionLibrary::IsAnchorResultSuccess(SetStatusResult))
|
||||
{
|
||||
Success.Broadcast(TargetAnchorComponent, SpaceComponentType, bResultEnabled, SetStatusResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
Failure.Broadcast(SetStatusResult);
|
||||
}
|
||||
|
||||
SetReadyToDestroy();
|
||||
}
|
||||
|
||||
//
|
||||
// Set Component Status
|
||||
//
|
||||
void UOculusXRAsyncAction_SetComponentStatus::Activate()
|
||||
{
|
||||
EOculusXRAnchorResult::Type Result;
|
||||
bool bStartedAsync = OculusXRAnchors::FOculusXRAnchors::SetComponentStatus(
|
||||
Component->GetSpace(),
|
||||
Component->GetType(),
|
||||
bEnabled,
|
||||
0,
|
||||
FOculusXRAnchorSetComponentStatusDelegate::CreateUObject(this, &UOculusXRAsyncAction_SetComponentStatus::HandleSetComponentStatusComplete),
|
||||
Result);
|
||||
|
||||
if (!bStartedAsync)
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("Failed to start async OVR Plugin call for SetComponentStatus latent action."));
|
||||
|
||||
Failure.Broadcast(Result);
|
||||
}
|
||||
}
|
||||
|
||||
UOculusXRAsyncAction_SetComponentStatus* UOculusXRAsyncAction_SetComponentStatus::OculusXRAsyncSetComponentStatus(UOculusXRBaseAnchorComponent* Component, bool bEnabled)
|
||||
{
|
||||
UOculusXRAsyncAction_SetComponentStatus* Action = NewObject<UOculusXRAsyncAction_SetComponentStatus>();
|
||||
Action->Component = Component;
|
||||
Action->bEnabled = bEnabled;
|
||||
|
||||
Action->RegisterWithGameInstance(GWorld);
|
||||
|
||||
return Action;
|
||||
}
|
||||
|
||||
void UOculusXRAsyncAction_SetComponentStatus::HandleSetComponentStatusComplete(EOculusXRAnchorResult::Type SetStatusResult, uint64 AnchorHandle, EOculusXRSpaceComponentType SpaceComponentType, bool bResultEnabled)
|
||||
{
|
||||
if (UOculusXRAnchorBPFunctionLibrary::IsAnchorResultSuccess(SetStatusResult))
|
||||
{
|
||||
Success.Broadcast(Component, SetStatusResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
Failure.Broadcast(SetStatusResult);
|
||||
}
|
||||
|
||||
SetReadyToDestroy();
|
||||
}
|
||||
|
||||
//
|
||||
// Share Spaces
|
||||
//
|
||||
void UOculusXRAsyncAction_ShareAnchors::Activate()
|
||||
{
|
||||
if (TargetAnchors.Num() == 0)
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("Empty Target Actors array passed to ShareSpaces latent action."));
|
||||
|
||||
Failure.Broadcast(EOculusXRAnchorResult::Failure);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ToShareWithIds.Num() == 0)
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("Empty Target Player IDs array passed to ShareSpaces latent action."));
|
||||
|
||||
Failure.Broadcast(EOculusXRAnchorResult::Failure);
|
||||
return;
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type Result;
|
||||
bool bStartedAsync = OculusXRAnchors::FOculusXRAnchors::ShareAnchors(
|
||||
TargetAnchors,
|
||||
ToShareWithIds,
|
||||
FOculusXRAnchorShareDelegate::CreateUObject(this, &UOculusXRAsyncAction_ShareAnchors::HandleShareAnchorsComplete),
|
||||
Result);
|
||||
|
||||
if (!bStartedAsync)
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("Failed to start async OVR Plugin call for ShareSpaces latent action."));
|
||||
|
||||
Failure.Broadcast(Result);
|
||||
}
|
||||
}
|
||||
|
||||
UOculusXRAsyncAction_ShareAnchors* UOculusXRAsyncAction_ShareAnchors::OculusXRAsyncShareAnchors(const TArray<AActor*>& TargetActors, const TArray<FString>& ToShareWithIds)
|
||||
{
|
||||
UOculusXRAsyncAction_ShareAnchors* Action = NewObject<UOculusXRAsyncAction_ShareAnchors>();
|
||||
|
||||
for (const auto& UserIDString : ToShareWithIds)
|
||||
{
|
||||
uint64 UserId = FCString::Strtoui64(*UserIDString, nullptr, 10);
|
||||
if (UserId == 0)
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("UserID provided to share anchors was invalid or unconvertable: %s"), *UserIDString);
|
||||
}
|
||||
|
||||
Action->ToShareWithIds.Add(UserId);
|
||||
}
|
||||
|
||||
for (auto& it : TargetActors)
|
||||
{
|
||||
if (!IsValid(it))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
UOculusXRAnchorComponent* AnchorComponent = it->FindComponentByClass<UOculusXRAnchorComponent>();
|
||||
Action->TargetAnchors.Add(AnchorComponent);
|
||||
}
|
||||
|
||||
auto ValidActorPtr = TargetActors.FindByPredicate([](AActor* Actor) { return IsValid(Actor); });
|
||||
if (ValidActorPtr != nullptr)
|
||||
{
|
||||
Action->RegisterWithGameInstance(*ValidActorPtr);
|
||||
}
|
||||
else
|
||||
{
|
||||
Action->RegisterWithGameInstance(GWorld);
|
||||
}
|
||||
|
||||
return Action;
|
||||
}
|
||||
|
||||
void UOculusXRAsyncAction_ShareAnchors::HandleShareAnchorsComplete(EOculusXRAnchorResult::Type ShareResult, const TArray<UOculusXRAnchorComponent*>& SharedAnchors, const TArray<uint64>& OculusUserIDs)
|
||||
{
|
||||
TArray<FString> OculusUserIDStrings;
|
||||
for (const auto& it : OculusUserIDs)
|
||||
{
|
||||
OculusUserIDStrings.Add(FString::Printf(TEXT("%llu"), it));
|
||||
}
|
||||
|
||||
if (UOculusXRAnchorBPFunctionLibrary::IsAnchorResultSuccess(ShareResult))
|
||||
{
|
||||
Success.Broadcast(SharedAnchors, OculusUserIDStrings, ShareResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
Failure.Broadcast(ShareResult);
|
||||
}
|
||||
|
||||
// Unbind and mark for destruction
|
||||
SetReadyToDestroy();
|
||||
}
|
||||
|
||||
//
|
||||
// Save Anchors
|
||||
//
|
||||
void UOculusXRAsyncAction_SaveAnchors::Activate()
|
||||
{
|
||||
if (TargetAnchors.Num() == 0)
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("Empty Target Actor array passed to SaveSpaces latent action."));
|
||||
|
||||
Failure.Broadcast(EOculusXRAnchorResult::Failure);
|
||||
return;
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type Result;
|
||||
bool bStartedAsync = OculusXRAnchors::FOculusXRAnchors::SaveAnchors(
|
||||
TargetAnchors,
|
||||
FOculusXRSaveAnchorsDelegate::CreateUObject(this, &UOculusXRAsyncAction_SaveAnchors::HandleSaveAnchorsComplete),
|
||||
Result);
|
||||
|
||||
if (!bStartedAsync)
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("Failed to start async OVR Plugin call for SaveSpaces latent action."));
|
||||
|
||||
Failure.Broadcast(Result);
|
||||
}
|
||||
}
|
||||
|
||||
UOculusXRAsyncAction_SaveAnchors* UOculusXRAsyncAction_SaveAnchors::OculusXRAsyncSaveAnchors(const TArray<AActor*>& TargetActors)
|
||||
{
|
||||
UOculusXRAsyncAction_SaveAnchors* Action = NewObject<UOculusXRAsyncAction_SaveAnchors>();
|
||||
|
||||
auto ValidActorPtr = TargetActors.FindByPredicate([](AActor* Actor) { return IsValid(Actor); });
|
||||
|
||||
for (auto& it : TargetActors)
|
||||
{
|
||||
if (!IsValid(it))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
UOculusXRAnchorComponent* AnchorComponent = it->FindComponentByClass<UOculusXRAnchorComponent>();
|
||||
Action->TargetAnchors.Add(AnchorComponent);
|
||||
}
|
||||
|
||||
if (ValidActorPtr != nullptr)
|
||||
{
|
||||
Action->RegisterWithGameInstance(*ValidActorPtr);
|
||||
}
|
||||
|
||||
return Action;
|
||||
}
|
||||
|
||||
void UOculusXRAsyncAction_SaveAnchors::HandleSaveAnchorsComplete(EOculusXRAnchorResult::Type SaveResult, const TArray<UOculusXRAnchorComponent*>& SavedSpaces)
|
||||
{
|
||||
if (UOculusXRAnchorBPFunctionLibrary::IsAnchorResultSuccess(SaveResult))
|
||||
{
|
||||
Success.Broadcast(SavedSpaces, SaveResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
Failure.Broadcast(SaveResult);
|
||||
}
|
||||
|
||||
SetReadyToDestroy();
|
||||
}
|
||||
|
||||
//
|
||||
// Erase Anchors
|
||||
//
|
||||
void UOculusXRAsyncAction_EraseAnchors::Activate()
|
||||
{
|
||||
if (TargetAnchorHandles.IsEmpty() && TargetUUIDs.IsEmpty())
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Error, TEXT("Empty UUID and Anchor Handles arrays passed to erase anchors. Check that at least one of the anchors, handles, and UUIDs arrays provided have valid elements."));
|
||||
Failure.Broadcast(EOculusXRAnchorResult::Failure);
|
||||
return;
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type Result;
|
||||
bool bStartedAsync = OculusXRAnchors::FOculusXRAnchors::EraseAnchors(
|
||||
TargetAnchorHandles,
|
||||
TargetUUIDs,
|
||||
FOculusXREraseAnchorsDelegate::CreateUObject(this, &UOculusXRAsyncAction_EraseAnchors::HandleEraseAnchorsComplete),
|
||||
Result);
|
||||
|
||||
if (!bStartedAsync)
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("Failed to start async OVR Plugin call for EraseSpace latent action."));
|
||||
Failure.Broadcast(Result);
|
||||
}
|
||||
}
|
||||
|
||||
UOculusXRAsyncAction_EraseAnchors* UOculusXRAsyncAction_EraseAnchors::OculusXRAsyncEraseAnchors(const TArray<AActor*>& TargetActors, const TArray<FOculusXRUInt64>& AnchorHandles, const TArray<FOculusXRUUID>& AnchorUUIDs)
|
||||
{
|
||||
UOculusXRAsyncAction_EraseAnchors* Action = NewObject<UOculusXRAsyncAction_EraseAnchors>();
|
||||
|
||||
Action->TargetAnchorHandles = AnchorHandles;
|
||||
Action->TargetUUIDs = AnchorUUIDs;
|
||||
|
||||
auto ValidActorPtr = TargetActors.FindByPredicate([](AActor* Actor) { return IsValid(Actor); });
|
||||
|
||||
for (auto& it : TargetActors)
|
||||
{
|
||||
if (!IsValid(it))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
UOculusXRAnchorComponent* AnchorComponent = it->FindComponentByClass<UOculusXRAnchorComponent>();
|
||||
if (!IsValid(it))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Action->TargetAnchors.Add(AnchorComponent);
|
||||
|
||||
auto UUID = AnchorComponent->GetUUID();
|
||||
Action->TargetUUIDs.Add(UUID);
|
||||
}
|
||||
|
||||
if (ValidActorPtr != nullptr)
|
||||
{
|
||||
Action->RegisterWithGameInstance(*ValidActorPtr);
|
||||
}
|
||||
else
|
||||
{
|
||||
Action->RegisterWithGameInstance(GWorld);
|
||||
}
|
||||
|
||||
return Action;
|
||||
}
|
||||
|
||||
void UOculusXRAsyncAction_EraseAnchors::HandleEraseAnchorsComplete(EOculusXRAnchorResult::Type EraseResult, const TArray<UOculusXRAnchorComponent*>& ErasedAnchorComponents, const TArray<FOculusXRUInt64>& ErasedAnchorHandles, const TArray<FOculusXRUUID>& ErasedAnchorUUIDs)
|
||||
{
|
||||
if (UOculusXRAnchorBPFunctionLibrary::IsAnchorResultSuccess(EraseResult))
|
||||
{
|
||||
Success.Broadcast(TargetAnchors, ErasedAnchorHandles, ErasedAnchorUUIDs, EraseResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
Failure.Broadcast(EraseResult);
|
||||
}
|
||||
|
||||
SetReadyToDestroy();
|
||||
}
|
||||
|
||||
//
|
||||
// Anchors Discovery
|
||||
//
|
||||
void UOculusXRAsyncAction_DiscoverAnchors::Activate()
|
||||
{
|
||||
EOculusXRAnchorResult::Type Result;
|
||||
bool bStartedAsync = OculusXRAnchors::FOculusXRAnchors::DiscoverAnchors(
|
||||
DiscoveryInfo,
|
||||
FOculusXRDiscoverAnchorsResultsDelegate::CreateUObject(this, &UOculusXRAsyncAction_DiscoverAnchors::HandleDiscoverResult),
|
||||
FOculusXRDiscoverAnchorsCompleteDelegate::CreateUObject(this, &UOculusXRAsyncAction_DiscoverAnchors::HandleDiscoverComplete),
|
||||
Result);
|
||||
|
||||
if (!bStartedAsync)
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("Failed to start async OVR Plugin call for DiscoverAnchors latent action."));
|
||||
|
||||
Failure.Broadcast(Result);
|
||||
}
|
||||
}
|
||||
|
||||
UOculusXRAsyncAction_DiscoverAnchors* UOculusXRAsyncAction_DiscoverAnchors::OculusXRAsyncDiscoverAnchors(const FOculusXRSpaceDiscoveryInfo& DiscoveryInfo)
|
||||
{
|
||||
UOculusXRAsyncAction_DiscoverAnchors* Action = NewObject<UOculusXRAsyncAction_DiscoverAnchors>();
|
||||
Action->DiscoveryInfo = DiscoveryInfo;
|
||||
|
||||
return Action;
|
||||
}
|
||||
|
||||
void UOculusXRAsyncAction_DiscoverAnchors::HandleDiscoverResult(const TArray<FOculusXRAnchorsDiscoverResult>& DiscoveredAnchors)
|
||||
{
|
||||
Discovered.Broadcast(DiscoveredAnchors);
|
||||
}
|
||||
|
||||
void UOculusXRAsyncAction_DiscoverAnchors::HandleDiscoverComplete(EOculusXRAnchorResult::Type CompleteResult)
|
||||
{
|
||||
if (UOculusXRAnchorBPFunctionLibrary::IsAnchorResultSuccess(CompleteResult))
|
||||
{
|
||||
Complete.Broadcast(CompleteResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
Failure.Broadcast(CompleteResult);
|
||||
}
|
||||
|
||||
SetReadyToDestroy();
|
||||
}
|
||||
|
||||
//
|
||||
// Get Shared Anchors
|
||||
//
|
||||
void UOculusXRAsyncAction_GetSharedAnchors::Activate()
|
||||
{
|
||||
EOculusXRAnchorResult::Type Result;
|
||||
bool bStartedAsync = OculusXRAnchors::FOculusXRAnchors::GetSharedAnchors(
|
||||
Anchors,
|
||||
FOculusXRGetSharedAnchorsDelegate::CreateUObject(this, &UOculusXRAsyncAction_GetSharedAnchors::HandleGetSharedAnchorsResult),
|
||||
Result);
|
||||
|
||||
if (!bStartedAsync)
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("Failed to start async OVR Plugin call for DiscoverAnchors latent action."));
|
||||
Failure.Broadcast(Result);
|
||||
}
|
||||
}
|
||||
|
||||
UOculusXRAsyncAction_GetSharedAnchors* UOculusXRAsyncAction_GetSharedAnchors::OculusXRAsyncGetSharedAnchors(const TArray<FOculusXRUUID>& AnchorUUIDs)
|
||||
{
|
||||
UOculusXRAsyncAction_GetSharedAnchors* Action = NewObject<UOculusXRAsyncAction_GetSharedAnchors>();
|
||||
Action->Anchors = AnchorUUIDs;
|
||||
|
||||
return Action;
|
||||
}
|
||||
|
||||
void UOculusXRAsyncAction_GetSharedAnchors::HandleGetSharedAnchorsResult(EOculusXRAnchorResult::Type Result, const TArray<FOculusXRAnchorsDiscoverResult>& SharedAnchors)
|
||||
{
|
||||
if (UOculusXRAnchorBPFunctionLibrary::IsAnchorResultSuccess(Result))
|
||||
{
|
||||
Success.Broadcast(SharedAnchors, Result);
|
||||
}
|
||||
else
|
||||
{
|
||||
Failure.Broadcast(Result);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Share with groups
|
||||
//
|
||||
void UOculusXRAsyncAction_ShareAnchorsWithGroups::Activate()
|
||||
{
|
||||
OculusXRAnchors::FOculusXRAnchors::ShareAnchorsAsync(
|
||||
AnchorHandles,
|
||||
GroupUUIDs,
|
||||
OculusXRAnchors::FShareAnchorsWithGroups::FCompleteDelegate::CreateUObject(
|
||||
this,
|
||||
&UOculusXRAsyncAction_ShareAnchorsWithGroups::HandleShareComplete));
|
||||
}
|
||||
|
||||
UOculusXRAsyncAction_ShareAnchorsWithGroups* UOculusXRAsyncAction_ShareAnchorsWithGroups::OculusXRShareAnchorsWithGroupsAsync(const TArray<FOculusXRUUID>& GroupUUIDs, const TArray<FOculusXRUInt64>& AnchorHandles)
|
||||
{
|
||||
UOculusXRAsyncAction_ShareAnchorsWithGroups* Action = NewObject<UOculusXRAsyncAction_ShareAnchorsWithGroups>();
|
||||
Action->GroupUUIDs = GroupUUIDs;
|
||||
Action->AnchorHandles = AnchorHandles;
|
||||
Action->RegisterWithGameInstance(GWorld);
|
||||
|
||||
return Action;
|
||||
}
|
||||
|
||||
void UOculusXRAsyncAction_ShareAnchorsWithGroups::HandleShareComplete(const OculusXRAnchors::FShareAnchorsWithGroups::FResultType& Result)
|
||||
{
|
||||
if (Result.IsSuccess())
|
||||
{
|
||||
Complete.Broadcast(Result.IsSuccess(), GroupUUIDs, AnchorHandles, Result.GetStatus());
|
||||
}
|
||||
else
|
||||
{
|
||||
Complete.Broadcast(Result.IsSuccess(), TArray<FOculusXRUUID>(), TArray<FOculusXRUInt64>(), Result.GetStatus());
|
||||
}
|
||||
|
||||
SetReadyToDestroy();
|
||||
}
|
||||
|
||||
//
|
||||
// Get shared anchors from group
|
||||
//
|
||||
void UOculusXRAsyncAction_GetSharedAnchorsFromGroup::Activate()
|
||||
{
|
||||
OculusXRAnchors::FOculusXRAnchors::GetSharedAnchorsAsync(
|
||||
GroupUuid,
|
||||
Anchors,
|
||||
OculusXRAnchors::FGetAnchorsSharedWithGroup::FCompleteDelegate::CreateUObject(
|
||||
this,
|
||||
&UOculusXRAsyncAction_GetSharedAnchorsFromGroup::HandleGetSharedAnchorsComplete));
|
||||
}
|
||||
|
||||
UOculusXRAsyncAction_GetSharedAnchorsFromGroup* UOculusXRAsyncAction_GetSharedAnchorsFromGroup::OculusXRGetSharedAnchorsFromGroupAsync(const FOculusXRUUID& GroupUuid, const TArray<FOculusXRUUID>& AnchorUUIDs)
|
||||
{
|
||||
UOculusXRAsyncAction_GetSharedAnchorsFromGroup* Action = NewObject<UOculusXRAsyncAction_GetSharedAnchorsFromGroup>();
|
||||
Action->GroupUuid = GroupUuid;
|
||||
Action->Anchors = AnchorUUIDs;
|
||||
Action->RegisterWithGameInstance(GWorld);
|
||||
|
||||
return Action;
|
||||
}
|
||||
|
||||
void UOculusXRAsyncAction_GetSharedAnchorsFromGroup::HandleGetSharedAnchorsComplete(const OculusXRAnchors::FGetAnchorsSharedWithGroup::FResultType& Result)
|
||||
{
|
||||
if (Result.IsSuccess())
|
||||
{
|
||||
Complete.Broadcast(Result.IsSuccess(), Result.GetValue(), Result.GetStatus());
|
||||
}
|
||||
else
|
||||
{
|
||||
Complete.Broadcast(Result.IsSuccess(), OculusXRAnchors::FGetAnchorsSharedWithGroup::FResultValueType(), Result.GetStatus());
|
||||
}
|
||||
|
||||
SetReadyToDestroy();
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
#include "OculusXRAnchorManager.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "OculusXRHMD.h"
|
||||
#include "OculusXRAnchorsModule.h"
|
||||
#include "OculusXRAnchorDelegates.h"
|
||||
#include "OculusXRAnchorBPFunctionLibrary.h"
|
||||
#include "OculusXRAnchorTypesPrivate.h"
|
||||
|
||||
#include "OculusXRAnchorFunctionsOVR.h"
|
||||
#include "OculusXRAnchorFunctionsOpenXR.h"
|
||||
|
||||
namespace OculusXRAnchors
|
||||
{
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorManager::CreateAnchor(const FTransform& InTransform, uint64& OutRequestId, const FTransform& CameraTransform)
|
||||
{
|
||||
return GetOculusXRAnchorFunctionsImpl()->CreateAnchor(InTransform, OutRequestId, CameraTransform);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorManager::DestroyAnchor(uint64 AnchorHandle)
|
||||
{
|
||||
return GetOculusXRAnchorFunctionsImpl()->DestroyAnchor(AnchorHandle);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorManager::TryGetAnchorTransform(uint64 AnchorHandle, FTransform& OutTransform, FOculusXRAnchorLocationFlags& OutLocationFlags, EOculusXRAnchorSpace Space)
|
||||
{
|
||||
return GetOculusXRAnchorFunctionsImpl()->TryGetAnchorTransform(AnchorHandle, OutTransform, OutLocationFlags, Space);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorManager::SetAnchorComponentStatus(uint64 AnchorHandle, EOculusXRSpaceComponentType ComponentType, bool Enable, float Timeout, uint64& OutRequestId)
|
||||
{
|
||||
return GetOculusXRAnchorFunctionsImpl()->SetAnchorComponentStatus(AnchorHandle, ComponentType, Enable, Timeout, OutRequestId);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorManager::GetAnchorComponentStatus(uint64 AnchorHandle, EOculusXRSpaceComponentType ComponentType, bool& OutEnabled, bool& OutChangePending)
|
||||
{
|
||||
return GetOculusXRAnchorFunctionsImpl()->GetAnchorComponentStatus(AnchorHandle, ComponentType, OutEnabled, OutChangePending);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorManager::GetSupportedAnchorComponents(uint64 AnchorHandle, TArray<EOculusXRSpaceComponentType>& OutSupportedTypes)
|
||||
{
|
||||
return GetOculusXRAnchorFunctionsImpl()->GetSupportedAnchorComponents(AnchorHandle, OutSupportedTypes);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorManager::GetAnchorContainerUUIDs(uint64 AnchorHandle, TArray<FOculusXRUUID>& OutUUIDs)
|
||||
{
|
||||
return GetOculusXRAnchorFunctionsImpl()->GetAnchorContainerUUIDs(AnchorHandle, OutUUIDs);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorManager::SaveAnchor(uint64 AnchorHandle, EOculusXRSpaceStorageLocation StorageLocation, EOculusXRSpaceStoragePersistenceMode StoragePersistenceMode, uint64& OutRequestId)
|
||||
{
|
||||
return GetOculusXRAnchorFunctionsImpl()->SaveAnchor(AnchorHandle, StorageLocation, StoragePersistenceMode, OutRequestId);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorManager::SaveAnchorList(const TArray<uint64>& AnchorHandles, EOculusXRSpaceStorageLocation StorageLocation, uint64& OutRequestId)
|
||||
{
|
||||
return GetOculusXRAnchorFunctionsImpl()->SaveAnchorList(AnchorHandles, StorageLocation, OutRequestId);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorManager::SaveAnchors(const TArray<uint64>& AnchorHandles, uint64& OutRequestId)
|
||||
{
|
||||
return GetOculusXRAnchorFunctionsImpl()->SaveAnchors(AnchorHandles, OutRequestId);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorManager::DiscoverAnchors(const FOculusXRSpaceDiscoveryInfo& DiscoveryInfo, uint64& OutRequestId)
|
||||
{
|
||||
return GetOculusXRAnchorFunctionsImpl()->DiscoverAnchors(DiscoveryInfo, OutRequestId);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorManager::QueryAnchors(const FOculusXRSpaceQueryInfo& QueryInfo, uint64& OutRequestId)
|
||||
{
|
||||
return GetOculusXRAnchorFunctionsImpl()->QueryAnchors(QueryInfo, OutRequestId);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorManager::ShareAnchors(const TArray<uint64>& AnchorHandles, const TArray<uint64>& UserIds, uint64& OutRequestId)
|
||||
{
|
||||
return GetOculusXRAnchorFunctionsImpl()->ShareAnchors(AnchorHandles, UserIds, OutRequestId);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorManager::ShareAnchors(const TArray<uint64>& AnchorHandles, FOculusXRUUID GroupId, uint64& OutRequestId)
|
||||
{
|
||||
return GetOculusXRAnchorFunctionsImpl()->ShareAnchors(AnchorHandles, { GroupId }, OutRequestId);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorManager::ShareAnchors(const TArray<uint64>& AnchorHandles, const TArray<FOculusXRUUID>& Groups, uint64& OutRequestId)
|
||||
{
|
||||
return GetOculusXRAnchorFunctionsImpl()->ShareAnchors(AnchorHandles, Groups, OutRequestId);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorManager::EraseAnchor(uint64 AnchorHandle, EOculusXRSpaceStorageLocation StorageLocation, uint64& OutRequestId)
|
||||
{
|
||||
return GetOculusXRAnchorFunctionsImpl()->EraseAnchor(AnchorHandle, StorageLocation, OutRequestId);
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type FOculusXRAnchorManager::EraseAnchors(const TArray<FOculusXRUInt64>& AnchorHandles, const TArray<FOculusXRUUID>& UUIDs, uint64& OutRequestId)
|
||||
{
|
||||
return GetOculusXRAnchorFunctionsImpl()->EraseAnchors(AnchorHandles, UUIDs, OutRequestId);
|
||||
}
|
||||
|
||||
TSharedPtr<IOculusXRAnchorFunctions> FOculusXRAnchorManager::AnchorFunctionsImpl = nullptr;
|
||||
TSharedPtr<IOculusXRAnchorFunctions> FOculusXRAnchorManager::GetOculusXRAnchorFunctionsImpl()
|
||||
{
|
||||
if (AnchorFunctionsImpl == nullptr)
|
||||
{
|
||||
const FName SystemName(TEXT("OpenXR"));
|
||||
const bool IsOpenXR = GEngine->XRSystem.IsValid() && (GEngine->XRSystem->GetSystemName() == SystemName);
|
||||
if (OculusXRHMD::FOculusXRHMD::GetOculusXRHMD() != nullptr)
|
||||
{
|
||||
AnchorFunctionsImpl = MakeShared<FOculusXRAnchorFunctionsOVR>();
|
||||
}
|
||||
else if (IsOpenXR)
|
||||
{
|
||||
AnchorFunctionsImpl = MakeShared<FOculusXRAnchorFunctionsOpenXR>();
|
||||
}
|
||||
}
|
||||
|
||||
check(AnchorFunctionsImpl);
|
||||
return AnchorFunctionsImpl;
|
||||
}
|
||||
|
||||
} // namespace OculusXRAnchors
|
||||
@@ -0,0 +1,42 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "OculusXRAnchorComponent.h"
|
||||
#include "OculusXRHMDPrivate.h"
|
||||
#include "OVR_Plugin_Types.h"
|
||||
#include "OculusXRAnchorFunctions.h"
|
||||
|
||||
namespace OculusXRAnchors
|
||||
{
|
||||
struct OCULUSXRANCHORS_API FOculusXRAnchorManager
|
||||
{
|
||||
public:
|
||||
static EOculusXRAnchorResult::Type CreateAnchor(const FTransform& InTransform, uint64& OutRequestId, const FTransform& CameraTransform);
|
||||
static EOculusXRAnchorResult::Type DestroyAnchor(uint64 AnchorHandle);
|
||||
|
||||
static EOculusXRAnchorResult::Type TryGetAnchorTransform(uint64 AnchorHandle, FTransform& OutTransform, FOculusXRAnchorLocationFlags& OutLocationFlags, EOculusXRAnchorSpace Space);
|
||||
static EOculusXRAnchorResult::Type SetAnchorComponentStatus(uint64 AnchorHandle, EOculusXRSpaceComponentType ComponentType, bool Enable, float Timeout, uint64& OutRequestId);
|
||||
static EOculusXRAnchorResult::Type GetAnchorComponentStatus(uint64 AnchorHandle, EOculusXRSpaceComponentType ComponentType, bool& OutEnabled, bool& OutChangePending);
|
||||
static EOculusXRAnchorResult::Type GetSupportedAnchorComponents(uint64 AnchorHandle, TArray<EOculusXRSpaceComponentType>& OutSupportedTypes);
|
||||
static EOculusXRAnchorResult::Type GetAnchorContainerUUIDs(uint64 AnchorHandle, TArray<FOculusXRUUID>& OutUUIDs);
|
||||
|
||||
static EOculusXRAnchorResult::Type SaveAnchor(uint64 AnchorHandle, EOculusXRSpaceStorageLocation StorageLocation, EOculusXRSpaceStoragePersistenceMode StoragePersistenceMode, uint64& OutRequestId);
|
||||
static EOculusXRAnchorResult::Type SaveAnchorList(const TArray<uint64>& AnchorHandles, EOculusXRSpaceStorageLocation StorageLocation, uint64& OutRequestId);
|
||||
static EOculusXRAnchorResult::Type SaveAnchors(const TArray<uint64>& AnchorHandles, uint64& OutRequestId);
|
||||
|
||||
static EOculusXRAnchorResult::Type DiscoverAnchors(const FOculusXRSpaceDiscoveryInfo& DiscoveryInfo, uint64& OutRequestId);
|
||||
static EOculusXRAnchorResult::Type QueryAnchors(const FOculusXRSpaceQueryInfo& QueryInfo, uint64& OutRequestId);
|
||||
static EOculusXRAnchorResult::Type ShareAnchors(const TArray<uint64>& AnchorHandles, const TArray<uint64>& UserIds, uint64& OutRequestId);
|
||||
static EOculusXRAnchorResult::Type ShareAnchors(const TArray<uint64>& AnchorHandles, FOculusXRUUID GroupId, uint64& OutRequestId);
|
||||
static EOculusXRAnchorResult::Type ShareAnchors(const TArray<uint64>& AnchorHandles, const TArray<FOculusXRUUID>& Groups, uint64& OutRequestId);
|
||||
|
||||
static EOculusXRAnchorResult::Type EraseAnchor(uint64 AnchorHandle, EOculusXRSpaceStorageLocation StorageLocation, uint64& OutRequestId);
|
||||
static EOculusXRAnchorResult::Type EraseAnchors(const TArray<FOculusXRUInt64>& AnchorHandles, const TArray<FOculusXRUUID>& UUIDs, uint64& OutRequestId);
|
||||
|
||||
private:
|
||||
static TSharedPtr<IOculusXRAnchorFunctions> GetOculusXRAnchorFunctionsImpl();
|
||||
static TSharedPtr<IOculusXRAnchorFunctions> AnchorFunctionsImpl;
|
||||
};
|
||||
} // namespace OculusXRAnchors
|
||||
@@ -0,0 +1,151 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
#include "OculusXRAnchorsRequests.h"
|
||||
#include "OculusXRAnchorsUtil.h"
|
||||
#include "OculusXRHMDModule.h"
|
||||
#include "OculusXRAnchorsModule.h"
|
||||
#include "OculusXRAnchorManager.h"
|
||||
#include "OculusXRAnchorDelegates.h"
|
||||
|
||||
namespace OculusXRAnchors
|
||||
{
|
||||
OculusXR::FAsyncRequestBase::RequestId DetermineRequestId(EOculusXRAnchorResult::Type Result, uint64 Id)
|
||||
{
|
||||
return OVRP_SUCCESS(Result) ? OculusXR::FAsyncRequestBase::RequestId(Id) : OculusXR::FAsyncRequestBase::RequestId(OculusXR::INVALID_TASK_REQUEST_ID);
|
||||
}
|
||||
|
||||
FShareAnchorsWithGroups::FShareAnchorsWithGroups(const TArray<FOculusXRUUID>& TargetGroups, const TArray<FOculusXRUInt64>& AnchorsToShare)
|
||||
: Groups(TargetGroups)
|
||||
, Anchors(AnchorsToShare)
|
||||
{
|
||||
CallbackHandle = FOculusXRAnchorEventDelegates::OculusShareAnchorsComplete.AddStatic(&FShareAnchorsWithGroups::OnShareComplete);
|
||||
}
|
||||
|
||||
FShareAnchorsWithGroups::~FShareAnchorsWithGroups()
|
||||
{
|
||||
FOculusXRAnchorEventDelegates::OculusShareAnchorsComplete.Remove(CallbackHandle);
|
||||
}
|
||||
|
||||
void FShareAnchorsWithGroups::OnInitRequest()
|
||||
{
|
||||
TArray<uint64> anchorHandles;
|
||||
Algo::Transform(Anchors, anchorHandles, [](const FOculusXRUInt64& In) { return In.GetValue(); });
|
||||
|
||||
uint64 requestId;
|
||||
auto result = FOculusXRAnchorManager::ShareAnchors(anchorHandles, Groups, requestId);
|
||||
|
||||
SetRequestId(DetermineRequestId(result, requestId));
|
||||
SetInitialResult(result);
|
||||
|
||||
UE_LOG(LogOculusXRAnchors, Log, TEXT("Started FShareAnchorsWithGroups: RequestId: %llu -- EventId: %llu -- Result: %s"),
|
||||
GetRequestId().Id, GetEventId().Id, *GetStringFromResult(result));
|
||||
}
|
||||
|
||||
void FShareAnchorsWithGroups::OnShareComplete(FOculusXRUInt64 RequestId, EOculusXRAnchorResult::Type Result)
|
||||
{
|
||||
auto taskPtr = OculusXR::FAsyncRequestSystem::GetRequest<FShareAnchorsWithGroups>(
|
||||
OculusXR::FAsyncRequestBase::RequestId{ RequestId });
|
||||
|
||||
if (taskPtr.IsValid())
|
||||
{
|
||||
OculusXR::FAsyncRequestSystem::CompleteRequest<FShareAnchorsWithGroups>(
|
||||
taskPtr->GetEventId(),
|
||||
FShareAnchorsWithGroups::FResultType::FromResult(
|
||||
Result,
|
||||
FShareAnchorsWithGroups::FResultValueType(taskPtr->GetGroups(), taskPtr->GetAnchors())));
|
||||
}
|
||||
}
|
||||
|
||||
FGetAnchorsSharedWithGroup::FGetAnchorsSharedWithGroup(const FOculusXRUUID& TargetGroup, const TArray<FOculusXRUUID>& WantedAnchors)
|
||||
: Group(TargetGroup)
|
||||
, RequestedAnchors(WantedAnchors)
|
||||
{
|
||||
CallbackHandleComplete = FOculusXRAnchorEventDelegates::OculusSpaceQueryComplete.AddStatic(&FGetAnchorsSharedWithGroup::OnQueryComplete);
|
||||
CallbackHandleResults = FOculusXRAnchorEventDelegates::OculusSpaceQueryResult.AddStatic(&FGetAnchorsSharedWithGroup::OnQueryResultAvailable);
|
||||
}
|
||||
|
||||
FGetAnchorsSharedWithGroup::~FGetAnchorsSharedWithGroup()
|
||||
{
|
||||
FOculusXRAnchorEventDelegates::OculusSpaceQueryComplete.Remove(CallbackHandleComplete);
|
||||
FOculusXRAnchorEventDelegates::OculusSpaceQueryResult.Remove(CallbackHandleResults);
|
||||
}
|
||||
|
||||
void FGetAnchorsSharedWithGroup::OnResultsAvailable(const TArray<FOculusXRAnchor>& Results)
|
||||
{
|
||||
RetrievedAnchors += Results;
|
||||
}
|
||||
|
||||
void FGetAnchorsSharedWithGroup::OnInitRequest()
|
||||
{
|
||||
constexpr int32 maxSpaces = 1024;
|
||||
constexpr double timeout = 0;
|
||||
|
||||
FOculusXRSpaceQueryInfo queryInfo;
|
||||
queryInfo.FilterType = EOculusXRSpaceQueryFilterType::FilterByGroup;
|
||||
queryInfo.GroupUUIDFilter = Group;
|
||||
queryInfo.Location = EOculusXRSpaceStorageLocation::Cloud;
|
||||
queryInfo.MaxQuerySpaces = maxSpaces;
|
||||
queryInfo.Timeout = timeout;
|
||||
queryInfo.IDFilter = RequestedAnchors;
|
||||
|
||||
uint64 requestId;
|
||||
auto result = FOculusXRAnchorManager::QueryAnchors(queryInfo, requestId);
|
||||
|
||||
SetRequestId(DetermineRequestId(result, requestId));
|
||||
SetInitialResult(result);
|
||||
|
||||
UE_LOG(LogOculusXRAnchors, Log, TEXT("Started FGetAnchorsSharedWithGroup: RequestId: %llu -- EventId: %llu -- Result: %s"),
|
||||
GetRequestId().Id, GetEventId().Id, *GetStringFromResult(result));
|
||||
}
|
||||
|
||||
void FGetAnchorsSharedWithGroup::OnQueryComplete(FOculusXRUInt64 RequestId, EOculusXRAnchorResult::Type Result)
|
||||
{
|
||||
auto taskPtr = OculusXR::FAsyncRequestSystem::GetRequest<FGetAnchorsSharedWithGroup>(
|
||||
OculusXR::FAsyncRequestBase::RequestId{ RequestId.GetValue() });
|
||||
|
||||
// If there is a valid get shared anchors request we can complete and exit without firing legacy event delegates
|
||||
if (taskPtr.IsValid())
|
||||
{
|
||||
OculusXR::FAsyncRequestSystem::CompleteRequest<FGetAnchorsSharedWithGroup>(
|
||||
taskPtr->GetEventId(),
|
||||
FGetAnchorsSharedWithGroup::FResultType::FromResult(Result, taskPtr->GetRetrievedAnchors()));
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void FGetAnchorsSharedWithGroup::OnQueryResultAvailable(FOculusXRUInt64 RequestId, FOculusXRUInt64 AnchorHandle, FOculusXRUUID AnchorUuid)
|
||||
{
|
||||
auto taskPtr = OculusXR::FAsyncRequestSystem::GetRequest<FGetAnchorsSharedWithGroup>(
|
||||
OculusXR::FAsyncRequestBase::RequestId{ RequestId.GetValue() });
|
||||
|
||||
if (taskPtr.IsValid())
|
||||
{
|
||||
TArray<EOculusXRSpaceComponentType> supportedTypes;
|
||||
UE_LOG(LogOculusXRAnchors, Verbose, TEXT(" Found Element: Space: %llu -- UUID: %s"), AnchorHandle.Value, *AnchorUuid.ToString());
|
||||
|
||||
uint64 tempOut;
|
||||
FOculusXRAnchorManager::GetSupportedAnchorComponents(AnchorHandle, supportedTypes);
|
||||
|
||||
if (supportedTypes.Contains(EOculusXRSpaceComponentType::Locatable))
|
||||
{
|
||||
FOculusXRAnchorManager::SetAnchorComponentStatus(AnchorHandle, EOculusXRSpaceComponentType::Locatable, true, 0.0f, tempOut);
|
||||
}
|
||||
|
||||
if (supportedTypes.Contains(EOculusXRSpaceComponentType::Sharable))
|
||||
{
|
||||
FOculusXRAnchorManager::SetAnchorComponentStatus(AnchorHandle, EOculusXRSpaceComponentType::Sharable, true, 0.0f, tempOut);
|
||||
}
|
||||
|
||||
if (supportedTypes.Contains(EOculusXRSpaceComponentType::Storable))
|
||||
{
|
||||
FOculusXRAnchorManager::SetAnchorComponentStatus(AnchorHandle, EOculusXRSpaceComponentType::Storable, true, 0.0f, tempOut);
|
||||
}
|
||||
|
||||
taskPtr->OnResultsAvailable({ FOculusXRAnchor(AnchorHandle, AnchorUuid) });
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace OculusXRAnchors
|
||||
@@ -0,0 +1,134 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
#include "OculusXRAnchorTypes.h"
|
||||
#include "OculusXRHMDPrivate.h"
|
||||
#include "OculusXRAnchorsModule.h"
|
||||
#include "OculusXRAnchorTypesPrivate.h"
|
||||
|
||||
bool FOculusXRUInt64::operator==(const FOculusXRUInt64& Right) const
|
||||
{
|
||||
return IsEqual(Right);
|
||||
}
|
||||
bool FOculusXRUInt64::operator!=(const FOculusXRUInt64& Right) const
|
||||
{
|
||||
return !IsEqual(Right);
|
||||
}
|
||||
|
||||
FOculusXRUUID::FOculusXRUUID()
|
||||
{
|
||||
FMemory::Memzero(&UUIDBytes, OCULUSXR_UUID_SIZE);
|
||||
}
|
||||
|
||||
FOculusXRUUID::FOculusXRUUID(const UuidArray& In)
|
||||
{
|
||||
FMemory::Memcpy(UUIDBytes, In);
|
||||
}
|
||||
|
||||
bool FOculusXRUUID::operator==(const FOculusXRUUID& Right) const
|
||||
{
|
||||
return IsEqual(Right);
|
||||
}
|
||||
|
||||
bool FOculusXRUUID::operator!=(const FOculusXRUUID& Right) const
|
||||
{
|
||||
return !IsEqual(Right);
|
||||
}
|
||||
|
||||
bool FOculusXRUUID::IsValidUUID() const
|
||||
{
|
||||
static uint8 InvalidUUID[OCULUSXR_UUID_SIZE] = { 0 };
|
||||
|
||||
return FMemory::Memcmp(UUIDBytes, InvalidUUID, OCULUSXR_UUID_SIZE) != 0;
|
||||
}
|
||||
|
||||
bool FOculusXRUUID::IsEqual(const FOculusXRUUID& Other) const
|
||||
{
|
||||
return FMemory::Memcmp(UUIDBytes, Other.UUIDBytes, OCULUSXR_UUID_SIZE) == 0;
|
||||
}
|
||||
|
||||
bool FOculusXRUUID::NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess)
|
||||
{
|
||||
uint8 data[16] = { 0 };
|
||||
|
||||
for (uint8 i = 0; i < OCULUSXR_UUID_SIZE; ++i)
|
||||
{
|
||||
data[i] = UUIDBytes[i];
|
||||
};
|
||||
|
||||
for (uint8 i = 0; i < OCULUSXR_UUID_SIZE; ++i)
|
||||
{
|
||||
Ar << data[i];
|
||||
};
|
||||
|
||||
for (uint8 i = 0; i < OCULUSXR_UUID_SIZE; ++i)
|
||||
{
|
||||
UUIDBytes[i] = data[i];
|
||||
};
|
||||
|
||||
bOutSuccess = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
FArchive& operator<<(FArchive& Ar, FOculusXRUUID& UUID)
|
||||
{
|
||||
bool bOutSuccess = false;
|
||||
UUID.NetSerialize(Ar, nullptr, bOutSuccess);
|
||||
|
||||
return Ar;
|
||||
}
|
||||
|
||||
bool FOculusXRUUID::Serialize(FArchive& Ar)
|
||||
{
|
||||
Ar << *this;
|
||||
return true;
|
||||
}
|
||||
|
||||
FString FOculusXRUUID::ToString() const
|
||||
{
|
||||
return BytesToHex(UUIDBytes, OCULUSXR_UUID_SIZE);
|
||||
}
|
||||
|
||||
void ovrpSpaceDiscoveryFilterIdsDelete::operator()(ovrpSpaceDiscoveryFilterIds* ptr) const
|
||||
{
|
||||
if (ptr != nullptr)
|
||||
{
|
||||
delete ptr;
|
||||
ptr = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
const ovrpSpaceDiscoveryFilterHeader* UOculusXRSpaceDiscoveryIdsFilter::GenerateOVRPFilter()
|
||||
{
|
||||
uint32 IdsCount = (uint32)Uuids.Num();
|
||||
|
||||
wrappedUUIDs.SetNumZeroed(IdsCount);
|
||||
OVRPFilterIds.reset(new ovrpSpaceDiscoveryFilterIds{ ovrpSpaceDiscoveryFilterType_Ids, IdsCount });
|
||||
UE_LOG(LogOculusXRAnchors, Display, TEXT("UUID discovery filter:"));
|
||||
|
||||
for (uint32 i = 0; i < IdsCount; ++i)
|
||||
{
|
||||
FMemory::Memcpy(wrappedUUIDs[i].data, Uuids[i].UUIDBytes);
|
||||
UE_LOG(LogOculusXRAnchors, Display, TEXT("\t%s"), *Uuids[i].ToString());
|
||||
}
|
||||
|
||||
OVRPFilterIds->Uuids = reinterpret_cast<ovrpUuid*>(wrappedUUIDs.GetData());
|
||||
|
||||
return (const ovrpSpaceDiscoveryFilterHeader*)OVRPFilterIds.get();
|
||||
}
|
||||
|
||||
void ovrpSpaceDiscoveryFilterComponentsDelete::operator()(ovrpSpaceDiscoveryFilterComponents* ptr) const
|
||||
{
|
||||
if (ptr != nullptr)
|
||||
{
|
||||
delete ptr;
|
||||
ptr = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
const ovrpSpaceDiscoveryFilterHeader* UOculusXRSpaceDiscoveryComponentsFilter::GenerateOVRPFilter()
|
||||
{
|
||||
OVRPFilterComponent.reset(new ovrpSpaceDiscoveryFilterComponents{ ovrpSpaceDiscoveryFilterType_Components, ConvertToOvrpComponentType(ComponentType) });
|
||||
UE_LOG(LogOculusXRAnchors, Display, TEXT("Component discovery filter %d"), ComponentType);
|
||||
return (const ovrpSpaceDiscoveryFilterHeader*)OVRPFilterComponent.get();
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
#include "OculusXRAnchorTypesPrivate.h"
|
||||
|
||||
ovrpSpaceComponentType ConvertToOvrpComponentType(const EOculusXRSpaceComponentType ComponentType)
|
||||
{
|
||||
ovrpSpaceComponentType ovrpType = ovrpSpaceComponentType_Max;
|
||||
switch (ComponentType)
|
||||
{
|
||||
case EOculusXRSpaceComponentType::Locatable:
|
||||
ovrpType = ovrpSpaceComponentType_Locatable;
|
||||
break;
|
||||
case EOculusXRSpaceComponentType::Sharable:
|
||||
ovrpType = ovrpSpaceComponentType_Sharable;
|
||||
break;
|
||||
case EOculusXRSpaceComponentType::Storable:
|
||||
ovrpType = ovrpSpaceComponentType_Storable;
|
||||
break;
|
||||
case EOculusXRSpaceComponentType::ScenePlane:
|
||||
ovrpType = ovrpSpaceComponentType_Bounded2D;
|
||||
break;
|
||||
case EOculusXRSpaceComponentType::SceneVolume:
|
||||
ovrpType = ovrpSpaceComponentType_Bounded3D;
|
||||
break;
|
||||
case EOculusXRSpaceComponentType::SemanticClassification:
|
||||
ovrpType = ovrpSpaceComponentType_SemanticLabels;
|
||||
break;
|
||||
case EOculusXRSpaceComponentType::RoomLayout:
|
||||
ovrpType = ovrpSpaceComponentType_RoomLayout;
|
||||
break;
|
||||
case EOculusXRSpaceComponentType::SpaceContainer:
|
||||
ovrpType = ovrpSpaceComponentType_SpaceContainer;
|
||||
break;
|
||||
case EOculusXRSpaceComponentType::TriangleMesh:
|
||||
ovrpType = ovrpSpaceComponentType_TriangleMesh;
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
|
||||
return ovrpType;
|
||||
}
|
||||
|
||||
EOculusXRSpaceComponentType ConvertToUEComponentType(const ovrpSpaceComponentType ComponentType)
|
||||
{
|
||||
EOculusXRSpaceComponentType ueComponentType = EOculusXRSpaceComponentType::Undefined;
|
||||
switch (ComponentType)
|
||||
{
|
||||
case ovrpSpaceComponentType_Locatable:
|
||||
ueComponentType = EOculusXRSpaceComponentType::Locatable;
|
||||
break;
|
||||
case ovrpSpaceComponentType_Sharable:
|
||||
ueComponentType = EOculusXRSpaceComponentType::Sharable;
|
||||
break;
|
||||
case ovrpSpaceComponentType_Storable:
|
||||
ueComponentType = EOculusXRSpaceComponentType::Storable;
|
||||
break;
|
||||
case ovrpSpaceComponentType_Bounded2D:
|
||||
ueComponentType = EOculusXRSpaceComponentType::ScenePlane;
|
||||
break;
|
||||
case ovrpSpaceComponentType_Bounded3D:
|
||||
ueComponentType = EOculusXRSpaceComponentType::SceneVolume;
|
||||
break;
|
||||
case ovrpSpaceComponentType_SemanticLabels:
|
||||
ueComponentType = EOculusXRSpaceComponentType::SemanticClassification;
|
||||
break;
|
||||
case ovrpSpaceComponentType_RoomLayout:
|
||||
ueComponentType = EOculusXRSpaceComponentType::RoomLayout;
|
||||
break;
|
||||
case ovrpSpaceComponentType_SpaceContainer:
|
||||
ueComponentType = EOculusXRSpaceComponentType::SpaceContainer;
|
||||
break;
|
||||
case ovrpSpaceComponentType_TriangleMesh:
|
||||
ueComponentType = EOculusXRSpaceComponentType::TriangleMesh;
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
|
||||
return ueComponentType;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
#pragma once
|
||||
#include "OculusXRAnchorTypes.h"
|
||||
#include "OVR_Plugin_Types.h"
|
||||
|
||||
ovrpSpaceComponentType ConvertToOvrpComponentType(const EOculusXRSpaceComponentType ComponentType);
|
||||
EOculusXRSpaceComponentType ConvertToUEComponentType(const ovrpSpaceComponentType ComponentType);
|
||||
1119
Plugins/MetaXR/Source/OculusXRAnchors/Private/OculusXRAnchors.cpp
Normal file
1119
Plugins/MetaXR/Source/OculusXRAnchors/Private/OculusXRAnchors.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,355 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
#include "OculusXRAnchorsEventPolling.h"
|
||||
#include "OculusXRHMD.h"
|
||||
#include "OculusXRAnchorsModule.h"
|
||||
#include "OculusXRAnchorManager.h"
|
||||
#include "OculusXRAnchorDelegates.h"
|
||||
#include "OculusXRAnchorBPFunctionLibrary.h"
|
||||
#include "OculusXRAnchorTypesPrivate.h"
|
||||
#include "OculusXRAnchorsUtil.h"
|
||||
#include "Engine/Engine.h"
|
||||
#include <vector>
|
||||
|
||||
namespace OculusXRAnchors
|
||||
{
|
||||
template <typename T>
|
||||
void GetEventDataAs(ovrpEventDataBuffer& Buffer, T& OutEventData)
|
||||
{
|
||||
memcpy(&OutEventData, reinterpret_cast<uint8*>(&Buffer), sizeof(T));
|
||||
}
|
||||
|
||||
// For template specializations that use the legacy event padding
|
||||
constexpr size_t LegacyOffset = 8;
|
||||
template <typename T>
|
||||
void GetLegacyEventDataAs(ovrpEventDataBuffer& Buffer, T& OutEventData)
|
||||
{
|
||||
OutEventData.EventType = Buffer.EventType;
|
||||
memcpy(((uint8*)&OutEventData) + LegacyOffset, Buffer.EventData, sizeof(T) - LegacyOffset);
|
||||
}
|
||||
|
||||
#define DECLARE_EVENT_DATA_CAST_SPECIALIZATION(T) \
|
||||
template <> \
|
||||
void GetEventDataAs(ovrpEventDataBuffer& Buffer, T& OutEventData) \
|
||||
{ \
|
||||
GetLegacyEventDataAs<T>(Buffer, OutEventData); \
|
||||
}
|
||||
|
||||
DECLARE_EVENT_DATA_CAST_SPECIALIZATION(ovrpEventDataSpatialAnchorCreateComplete);
|
||||
DECLARE_EVENT_DATA_CAST_SPECIALIZATION(ovrpEventDataSpaceSetStatusComplete);
|
||||
DECLARE_EVENT_DATA_CAST_SPECIALIZATION(ovrpEventSpaceQueryResults);
|
||||
DECLARE_EVENT_DATA_CAST_SPECIALIZATION(ovrpEventSpaceQueryComplete);
|
||||
DECLARE_EVENT_DATA_CAST_SPECIALIZATION(ovrpEventSpaceStorageSaveResult);
|
||||
DECLARE_EVENT_DATA_CAST_SPECIALIZATION(ovrpEventSpaceListSaveResult);
|
||||
DECLARE_EVENT_DATA_CAST_SPECIALIZATION(ovrpEventSpaceStorageEraseResult);
|
||||
DECLARE_EVENT_DATA_CAST_SPECIALIZATION(ovrpEventSpaceShareResult);
|
||||
DECLARE_EVENT_DATA_CAST_SPECIALIZATION(ovrpEventDataSpaceDiscoveryComplete);
|
||||
DECLARE_EVENT_DATA_CAST_SPECIALIZATION(ovrpEventSpaceDiscoveryResults);
|
||||
DECLARE_EVENT_DATA_CAST_SPECIALIZATION(ovrpEventSpacesSaveResult);
|
||||
DECLARE_EVENT_DATA_CAST_SPECIALIZATION(ovrpEventSpacesEraseResult);
|
||||
|
||||
void FOculusXRAnchorsEventPolling::OnPollEvent(ovrpEventDataBuffer* EventDataBuffer, bool& EventPollResult)
|
||||
{
|
||||
ovrpEventDataBuffer& buf = *EventDataBuffer;
|
||||
EventPollResult = true;
|
||||
|
||||
switch (buf.EventType)
|
||||
{
|
||||
case ovrpEventType_SpatialAnchorCreateComplete:
|
||||
{
|
||||
ovrpEventDataSpatialAnchorCreateComplete AnchorCreateEvent;
|
||||
GetEventDataAs(buf, AnchorCreateEvent);
|
||||
|
||||
const FOculusXRUInt64 RequestId(AnchorCreateEvent.requestId);
|
||||
const FOculusXRUInt64 Space(AnchorCreateEvent.space);
|
||||
const FOculusXRUUID BPUUID(AnchorCreateEvent.uuid.data);
|
||||
|
||||
FOculusXRAnchorEventDelegates::OculusSpatialAnchorCreateComplete.Broadcast(
|
||||
RequestId,
|
||||
GetResultFromOVRResult(AnchorCreateEvent.result),
|
||||
Space,
|
||||
BPUUID);
|
||||
|
||||
UE_LOG(LogOculusXRAnchors, Verbose, TEXT("ovrpEventType_SpatialAnchorCreateComplete Request ID: %llu -- Space: %llu -- UUID: %s -- Result: %d"),
|
||||
RequestId.GetValue(),
|
||||
Space.GetValue(),
|
||||
*BPUUID.ToString(),
|
||||
AnchorCreateEvent.result);
|
||||
|
||||
break;
|
||||
}
|
||||
case ovrpEventType_SpaceSetComponentStatusComplete:
|
||||
{
|
||||
ovrpEventDataSpaceSetStatusComplete SetStatusEvent;
|
||||
GetEventDataAs(buf, SetStatusEvent);
|
||||
|
||||
// translate to BP types
|
||||
const FOculusXRUInt64 RequestId(SetStatusEvent.requestId);
|
||||
const FOculusXRUInt64 Space(SetStatusEvent.space);
|
||||
EOculusXRSpaceComponentType BPSpaceComponentType = ConvertToUEComponentType(SetStatusEvent.componentType);
|
||||
const FOculusXRUUID BPUUID(SetStatusEvent.uuid.data);
|
||||
const bool bEnabled = (SetStatusEvent.enabled == ovrpBool_True);
|
||||
|
||||
FOculusXRAnchorEventDelegates::OculusSpaceSetComponentStatusComplete.Broadcast(
|
||||
RequestId,
|
||||
GetResultFromOVRResult(SetStatusEvent.result),
|
||||
Space,
|
||||
BPUUID,
|
||||
BPSpaceComponentType,
|
||||
bEnabled);
|
||||
|
||||
UE_LOG(LogOculusXRAnchors, Verbose, TEXT("ovrpEventType_SpaceSetComponentStatusComplete Request ID: %llu -- Type: %d -- Enabled: %d -- Space: %llu -- Result: %d"),
|
||||
SetStatusEvent.requestId,
|
||||
SetStatusEvent.componentType,
|
||||
SetStatusEvent.enabled,
|
||||
SetStatusEvent.space,
|
||||
SetStatusEvent.result);
|
||||
|
||||
break;
|
||||
}
|
||||
case ovrpEventType_SpaceQueryResults:
|
||||
{
|
||||
ovrpEventSpaceQueryResults QueryEvent;
|
||||
GetEventDataAs(buf, QueryEvent);
|
||||
|
||||
UE_LOG(LogOculusXRAnchors, Verbose, TEXT("ovrpEventType_SpaceQueryResults Request ID: %llu"), QueryEvent.requestId);
|
||||
|
||||
ovrpUInt32 ovrpOutCapacity = 0;
|
||||
auto getCapacityResult = FOculusXRHMDModule::GetPluginWrapper().RetrieveSpaceQueryResults(&QueryEvent.requestId, 0, &ovrpOutCapacity, nullptr);
|
||||
|
||||
UE_LOG(LogOculusXRAnchors, Verbose, TEXT("Space Query Results: Capacity Request -- Request ID: %llu -- Capacity: %d -- Result: %s"),
|
||||
QueryEvent.requestId,
|
||||
ovrpOutCapacity,
|
||||
*GetStringFromResult(GetResultFromOVRResult(getCapacityResult)));
|
||||
|
||||
std::vector<ovrpSpaceQueryResult> spaceQueryResults(ovrpOutCapacity);
|
||||
auto getQueryResult = FOculusXRHMDModule::GetPluginWrapper().RetrieveSpaceQueryResults(&QueryEvent.requestId, spaceQueryResults.size(), &ovrpOutCapacity, spaceQueryResults.data());
|
||||
|
||||
UE_LOG(LogOculusXRAnchors, Verbose, TEXT("Space Query Results: Retrieved Elements -- Request ID: %llu -- Result: %s"),
|
||||
QueryEvent.requestId,
|
||||
*GetStringFromResult(GetResultFromOVRResult(getQueryResult)));
|
||||
|
||||
if (OVRP_FAILURE(getCapacityResult) || OVRP_FAILURE(getQueryResult))
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("Failed to retrieve anchor data from space query results -- Request ID: %llu"), QueryEvent.requestId);
|
||||
return;
|
||||
}
|
||||
|
||||
FOculusXRUInt64 RequestId(QueryEvent.requestId);
|
||||
FOculusXRAnchorEventDelegates::OculusSpaceQueryResults.Broadcast(RequestId);
|
||||
|
||||
for (const auto& queryResultElement : spaceQueryResults)
|
||||
{
|
||||
FOculusXRUInt64 anchorHandle(queryResultElement.space);
|
||||
FOculusXRUUID uuid(queryResultElement.uuid.data);
|
||||
|
||||
UE_LOG(LogOculusXRAnchors, Verbose, TEXT("ovrpEventType_SpaceQueryResult -- Space: %llu -- UUID: %s"), anchorHandle.Value, *uuid.ToString());
|
||||
|
||||
FOculusXRAnchorEventDelegates::OculusSpaceQueryResult.Broadcast(RequestId, anchorHandle, uuid);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case ovrpEventType_SpaceQueryComplete:
|
||||
{
|
||||
ovrpEventSpaceQueryComplete QueryCompleteEvent;
|
||||
GetEventDataAs(buf, QueryCompleteEvent);
|
||||
|
||||
UE_LOG(LogOculusXRAnchors, Verbose, TEXT("ovrpEventType_SpaceQueryComplete Request ID: %llu -- Result: %d"), QueryCompleteEvent.requestId, QueryCompleteEvent.result);
|
||||
|
||||
// translate to BP types
|
||||
const FOculusXRUInt64 RequestId(QueryCompleteEvent.requestId);
|
||||
const bool bSucceeded = QueryCompleteEvent.result >= 0;
|
||||
|
||||
FOculusXRAnchorEventDelegates::OculusSpaceQueryComplete.Broadcast(
|
||||
RequestId,
|
||||
GetResultFromOVRResult(QueryCompleteEvent.result));
|
||||
|
||||
break;
|
||||
}
|
||||
case ovrpEventType_SpaceSaveComplete:
|
||||
{
|
||||
ovrpEventSpaceStorageSaveResult StorageResult;
|
||||
GetEventDataAs(buf, StorageResult);
|
||||
|
||||
// translate to BP types
|
||||
const FOculusXRUUID uuid(StorageResult.uuid.data);
|
||||
const FOculusXRUInt64 FSpace(StorageResult.space);
|
||||
const FOculusXRUInt64 FRequest(StorageResult.requestId);
|
||||
const bool bResult = StorageResult.result >= 0;
|
||||
|
||||
FOculusXRAnchorEventDelegates::OculusSpaceSaveComplete.Broadcast(
|
||||
FRequest,
|
||||
FSpace,
|
||||
bResult,
|
||||
GetResultFromOVRResult(StorageResult.result),
|
||||
uuid);
|
||||
|
||||
UE_LOG(LogOculusXRAnchors, Verbose, TEXT("ovrpEventType_SpaceSaveComplete Request ID: %llu -- Space: %llu -- Result: %d"), StorageResult.requestId, StorageResult.space, StorageResult.result);
|
||||
|
||||
break;
|
||||
}
|
||||
case ovrpEventType_SpaceListSaveResult:
|
||||
{
|
||||
ovrpEventSpaceListSaveResult SpaceListSaveResult;
|
||||
GetEventDataAs(buf, SpaceListSaveResult);
|
||||
|
||||
FOculusXRUInt64 RequestId(SpaceListSaveResult.requestId);
|
||||
|
||||
UE_LOG(LogOculusXRAnchors, Verbose, TEXT("ovrpEventType_SpaceListSaveResult Request ID: %llu -- Result: %d"), SpaceListSaveResult.requestId, SpaceListSaveResult.result);
|
||||
FOculusXRAnchorEventDelegates::OculusSpaceListSaveComplete.Broadcast(
|
||||
RequestId,
|
||||
GetResultFromOVRResult(SpaceListSaveResult.result));
|
||||
|
||||
break;
|
||||
}
|
||||
case ovrpEventType_SpaceEraseComplete:
|
||||
{
|
||||
ovrpEventSpaceStorageEraseResult SpaceEraseEvent;
|
||||
GetEventDataAs(buf, SpaceEraseEvent);
|
||||
|
||||
// translate to BP types
|
||||
const FOculusXRUUID uuid(SpaceEraseEvent.uuid.data);
|
||||
const FOculusXRUInt64 FRequestId(SpaceEraseEvent.requestId);
|
||||
const EOculusXRSpaceStorageLocation BPLocation = (SpaceEraseEvent.location == ovrpSpaceStorageLocation_Local) ? EOculusXRSpaceStorageLocation::Local : EOculusXRSpaceStorageLocation::Invalid;
|
||||
|
||||
UE_LOG(LogOculusXRAnchors, Verbose, TEXT("ovrpEventType_SpaceEraseComplete Request ID: %llu -- Result: %d -- UUID: %s"),
|
||||
SpaceEraseEvent.requestId,
|
||||
SpaceEraseEvent.result,
|
||||
*UOculusXRAnchorBPFunctionLibrary::AnchorUUIDToString(SpaceEraseEvent.uuid.data));
|
||||
|
||||
FOculusXRAnchorEventDelegates::OculusSpaceEraseComplete.Broadcast(
|
||||
FRequestId,
|
||||
GetResultFromOVRResult(SpaceEraseEvent.result),
|
||||
uuid,
|
||||
BPLocation);
|
||||
break;
|
||||
}
|
||||
case ovrpEventType_SpaceShareResult:
|
||||
{
|
||||
ovrpEventSpaceShareResult SpaceShareSpaceResult;
|
||||
GetEventDataAs(buf, SpaceShareSpaceResult);
|
||||
|
||||
FOculusXRUInt64 RequestId(SpaceShareSpaceResult.requestId);
|
||||
|
||||
UE_LOG(LogOculusXRAnchors, Verbose, TEXT("ovrpEventType_SpaceShareSpaceResult Request ID: %llu -- Result: %d"),
|
||||
SpaceShareSpaceResult.requestId,
|
||||
SpaceShareSpaceResult.result);
|
||||
|
||||
FOculusXRAnchorEventDelegates::OculusSpaceShareComplete.Broadcast(
|
||||
RequestId,
|
||||
GetResultFromOVRResult(SpaceShareSpaceResult.result));
|
||||
|
||||
break;
|
||||
}
|
||||
case ovrpEventType_SpaceDiscoveryComplete:
|
||||
{
|
||||
ovrpEventDataSpaceDiscoveryComplete SpaceDiscoveryCompleteEvent;
|
||||
GetEventDataAs(buf, SpaceDiscoveryCompleteEvent);
|
||||
|
||||
FOculusXRUInt64 RequestId(SpaceDiscoveryCompleteEvent.requestId);
|
||||
|
||||
UE_LOG(LogOculusXRAnchors, Verbose, TEXT("ovrpEventType_SpaceDiscoveryComplete Request ID: %llu -- Result: %d"),
|
||||
RequestId.GetValue(),
|
||||
SpaceDiscoveryCompleteEvent.result);
|
||||
|
||||
FOculusXRAnchorEventDelegates::OculusAnchorsDiscoverComplete.Broadcast(
|
||||
RequestId,
|
||||
GetResultFromOVRResult(SpaceDiscoveryCompleteEvent.result));
|
||||
|
||||
break;
|
||||
}
|
||||
case ovrpEventType_SpaceDiscoveryResultsAvailable:
|
||||
{
|
||||
ovrpEventSpaceDiscoveryResults SpaceDiscoveryResultsEvent;
|
||||
GetEventDataAs(buf, SpaceDiscoveryResultsEvent);
|
||||
|
||||
FOculusXRUInt64 RequestId(SpaceDiscoveryResultsEvent.requestId);
|
||||
|
||||
ovrpSpaceDiscoveryResults OVRPResults = { 0, 0, nullptr };
|
||||
|
||||
// get capacity
|
||||
bool GetCapacityResult = FOculusXRHMDModule::GetPluginWrapper().GetInitialized() && OVRP_SUCCESS(FOculusXRHMDModule::GetPluginWrapper().RetrieveSpaceDiscoveryResults(RequestId, &OVRPResults));
|
||||
|
||||
UE_LOG(LogOculusXRAnchors, Log, TEXT("ovrpEventType_SpaceDiscoveryResultsAvailable Request ID: %llu -- Capacity: %d -- Result: %d"),
|
||||
uint64(RequestId), OVRPResults.ResultCountOutput, GetCapacityResult);
|
||||
|
||||
// get data
|
||||
OVRPResults.ResultCapacityInput = OVRPResults.ResultCountOutput;
|
||||
std::vector<ovrpSpaceDiscoveryResult> ResultsData(OVRPResults.ResultCountOutput);
|
||||
OVRPResults.Results = ResultsData.data();
|
||||
bool GetDiscoveryResult = FOculusXRHMDModule::GetPluginWrapper().GetInitialized() && OVRP_SUCCESS(FOculusXRHMDModule::GetPluginWrapper().RetrieveSpaceDiscoveryResults(RequestId, &OVRPResults));
|
||||
TArray<FOculusXRAnchorsDiscoverResult> SpaceDiscoveryResults;
|
||||
|
||||
for (auto& Element : ResultsData)
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Verbose, TEXT("ovrpEventType_SpaceDiscoveryResultsAvailable Space: %llu -- Result: %d"),
|
||||
Element.Space,
|
||||
GetDiscoveryResult);
|
||||
|
||||
SpaceDiscoveryResults.Add(FOculusXRAnchorsDiscoverResult(Element.Space, Element.Uuid.data));
|
||||
}
|
||||
|
||||
FOculusXRAnchorEventDelegates::OculusAnchorsDiscoverResults.Broadcast(RequestId, SpaceDiscoveryResults);
|
||||
|
||||
break;
|
||||
}
|
||||
case ovrpEventType_SpacesSaveResult:
|
||||
{
|
||||
ovrpEventSpacesSaveResult SpacesSaveEvent;
|
||||
GetEventDataAs(buf, SpacesSaveEvent);
|
||||
|
||||
FOculusXRUInt64 RequestId(SpacesSaveEvent.requestId);
|
||||
|
||||
UE_LOG(LogOculusXRAnchors, Verbose, TEXT("ovrpEventType_SpacesSaveResult Request ID: %llu -- Result: %d"),
|
||||
RequestId.GetValue(),
|
||||
SpacesSaveEvent.result);
|
||||
|
||||
FOculusXRAnchorEventDelegates::OculusAnchorsSaveComplete.Broadcast(
|
||||
RequestId,
|
||||
GetResultFromOVRResult(SpacesSaveEvent.result));
|
||||
|
||||
break;
|
||||
}
|
||||
case ovrpEventType_SpacesEraseResult:
|
||||
{
|
||||
ovrpEventSpacesEraseResult SpacesEraseEvent;
|
||||
GetEventDataAs(buf, SpacesEraseEvent);
|
||||
|
||||
FOculusXRUInt64 RequestId(SpacesEraseEvent.requestId);
|
||||
FOculusXRUInt64 Result(SpacesEraseEvent.result);
|
||||
|
||||
UE_LOG(LogOculusXRAnchors, Verbose, TEXT("ovrpEventType_SpacesEraseResult Request ID: %llu -- Result: %d"),
|
||||
RequestId.GetValue(),
|
||||
SpacesEraseEvent.result);
|
||||
|
||||
FOculusXRAnchorEventDelegates::OculusAnchorsEraseComplete.Broadcast(
|
||||
RequestId,
|
||||
GetResultFromOVRResult(SpacesEraseEvent.result));
|
||||
|
||||
break;
|
||||
}
|
||||
case ovrpEventType_ShareSpacesComplete:
|
||||
{
|
||||
ovrpEventShareSpacesComplete EventData;
|
||||
GetEventDataAs(buf, EventData);
|
||||
|
||||
UE_LOG(LogOculusXRAnchors, Verbose, TEXT("ovrpEventType_ShareSpacesComplete Request ID: %llu -- Result: %s"),
|
||||
EventData.RequestId,
|
||||
*GetStringFromResult(GetResultFromOVRResult(EventData.Result)));
|
||||
|
||||
FOculusXRAnchorEventDelegates::OculusShareAnchorsComplete.Broadcast(
|
||||
EventData.RequestId,
|
||||
GetResultFromOVRResult(EventData.Result));
|
||||
|
||||
break;
|
||||
}
|
||||
case ovrpEventType_None:
|
||||
default:
|
||||
{
|
||||
EventPollResult = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace OculusXRAnchors
|
||||
@@ -0,0 +1,16 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "OculusXRAnchorTypes.h"
|
||||
#include "OculusXRPluginWrapper.h"
|
||||
|
||||
namespace OculusXRAnchors
|
||||
{
|
||||
struct FOculusXRAnchorsEventPolling
|
||||
{
|
||||
public:
|
||||
static void OnPollEvent(ovrpEventDataBuffer* EventDataBuffer, bool& EventPollResult);
|
||||
};
|
||||
|
||||
} // namespace OculusXRAnchors
|
||||
@@ -0,0 +1,109 @@
|
||||
// @lint-ignore-every LICENSELINT
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#include "OculusXRAnchorsModule.h"
|
||||
|
||||
#if OCULUS_ANCHORS_SUPPORTED_PLATFORMS
|
||||
#include "OculusXRHMDModule.h"
|
||||
#include "OculusXRHMD.h"
|
||||
#include "OculusXRAnchors.h"
|
||||
#include "OculusXRAnchorsEventPolling.h"
|
||||
#include "OculusXRAnchorComponents.h"
|
||||
|
||||
DEFINE_LOG_CATEGORY(LogOculusXRAnchors);
|
||||
|
||||
#define LOCTEXT_NAMESPACE "OculusXRAnchors"
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// FOculusXRAnchorsModule
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
void FOculusXRAnchorsModule::StartupModule()
|
||||
{
|
||||
AnchorsXR = MakeShareable(new XRAnchors::FAnchorsXR());
|
||||
AnchorsXR->RegisterAsOpenXRExtension();
|
||||
|
||||
AddCreateAnchorComponentInterface(this);
|
||||
Anchors.Initialize();
|
||||
|
||||
FCoreDelegates::OnPostEngineInit.AddRaw(this, &FOculusXRAnchorsModule::OnPostEngineInit);
|
||||
}
|
||||
|
||||
void FOculusXRAnchorsModule::ShutdownModule()
|
||||
{
|
||||
Anchors.Teardown();
|
||||
}
|
||||
|
||||
void FOculusXRAnchorsModule::OnPostEngineInit()
|
||||
{
|
||||
if (IsRunningCommandlet())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!GEngine)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
OculusXRHMD::FOculusXRHMD* HMD = OculusXRHMD::FOculusXRHMD::GetOculusXRHMD();
|
||||
if (!HMD)
|
||||
{
|
||||
UE_LOG(LogOculusXRAnchors, Warning, TEXT("Unable to retrieve OculusXRHMD, cannot add event polling delegates."));
|
||||
return;
|
||||
}
|
||||
|
||||
HMD->AddEventPollingDelegate(OculusXRHMD::FOculusXRHMDEventPollingDelegate::CreateStatic(&OculusXRAnchors::FOculusXRAnchorsEventPolling::OnPollEvent));
|
||||
}
|
||||
|
||||
void FOculusXRAnchorsModule::AddCreateAnchorComponentInterface(IOculusXRCreateAnchorComponent* CastInterface)
|
||||
{
|
||||
CreateComponentInterfaces.AddUnique(CastInterface);
|
||||
}
|
||||
|
||||
void FOculusXRAnchorsModule::RemoveCreateAnchorComponentInterface(IOculusXRCreateAnchorComponent* CastInterface)
|
||||
{
|
||||
CreateComponentInterfaces.Remove(CastInterface);
|
||||
}
|
||||
|
||||
UOculusXRBaseAnchorComponent* FOculusXRAnchorsModule::CreateAnchorComponent(uint64 AnchorHandle, EOculusXRSpaceComponentType Type, UObject* Outer)
|
||||
{
|
||||
for (auto& it : CreateComponentInterfaces)
|
||||
{
|
||||
auto comp = it->TryCreateAnchorComponent(AnchorHandle, Type, Outer);
|
||||
if (IsValid(comp))
|
||||
{
|
||||
return comp;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
UOculusXRBaseAnchorComponent* FOculusXRAnchorsModule::TryCreateAnchorComponent(uint64 AnchorHandle, EOculusXRSpaceComponentType Type, UObject* Outer)
|
||||
{
|
||||
switch (Type)
|
||||
{
|
||||
case EOculusXRSpaceComponentType::Locatable:
|
||||
return UOculusXRBaseAnchorComponent::FromSpace<UOculusXRLocatableAnchorComponent>(AnchorHandle, Outer);
|
||||
case EOculusXRSpaceComponentType::SpaceContainer:
|
||||
return UOculusXRBaseAnchorComponent::FromSpace<UOculusXRSpaceContainerAnchorComponent>(AnchorHandle, Outer);
|
||||
case EOculusXRSpaceComponentType::Sharable:
|
||||
return UOculusXRBaseAnchorComponent::FromSpace<UOculusXRSharableAnchorComponent>(AnchorHandle, Outer);
|
||||
case EOculusXRSpaceComponentType::Storable:
|
||||
return UOculusXRBaseAnchorComponent::FromSpace<UOculusXRStorableAnchorComponent>(AnchorHandle, Outer);
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
OculusXRAnchors::FOculusXRAnchors* FOculusXRAnchorsModule::GetOculusAnchors()
|
||||
{
|
||||
FOculusXRAnchorsModule& Module = FModuleManager::LoadModuleChecked<FOculusXRAnchorsModule>(TEXT("OculusXRAnchors"));
|
||||
return &Module.Anchors;
|
||||
}
|
||||
|
||||
#endif // OCULUS_ANCHORS_SUPPORTED_PLATFORMS
|
||||
|
||||
IMPLEMENT_MODULE(FOculusXRAnchorsModule, OculusXRAnchors)
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
@@ -0,0 +1,63 @@
|
||||
// @lint-ignore-every LICENSELINT
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
#include "IOculusXRAnchorsModule.h"
|
||||
#include "OculusXRAnchors.h"
|
||||
#include "openxr/OculusXRAnchorsXR.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "OculusAnchors"
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// FOculusXRAnchorsModule
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
#if OCULUS_ANCHORS_SUPPORTED_PLATFORMS
|
||||
|
||||
DECLARE_LOG_CATEGORY_EXTERN(LogOculusXRAnchors, Log, All);
|
||||
|
||||
typedef TSharedPtr<XRAnchors::FAnchorsXR, ESPMode::ThreadSafe> FAnchorsXRPtr;
|
||||
|
||||
class FOculusXRAnchorsModule : public IOculusXRAnchorsModule, IOculusXRCreateAnchorComponent
|
||||
{
|
||||
public:
|
||||
static inline FOculusXRAnchorsModule& Get()
|
||||
{
|
||||
return FModuleManager::LoadModuleChecked<FOculusXRAnchorsModule>("OculusXRAnchors");
|
||||
}
|
||||
|
||||
virtual ~FOculusXRAnchorsModule() = default;
|
||||
|
||||
// IModuleInterface interface
|
||||
virtual void StartupModule() override;
|
||||
virtual void ShutdownModule() override;
|
||||
|
||||
void OnPostEngineInit();
|
||||
|
||||
// IOculusXRAnchorsModule
|
||||
virtual void AddCreateAnchorComponentInterface(IOculusXRCreateAnchorComponent* CastInterface) override;
|
||||
virtual void RemoveCreateAnchorComponentInterface(IOculusXRCreateAnchorComponent* CastInterface) override;
|
||||
virtual UOculusXRBaseAnchorComponent* CreateAnchorComponent(uint64 AnchorHandle, EOculusXRSpaceComponentType Type, UObject* Outer) override;
|
||||
|
||||
// IOculusXRAnchorComponentCaster
|
||||
virtual UOculusXRBaseAnchorComponent* TryCreateAnchorComponent(uint64 AnchorHandle, EOculusXRSpaceComponentType Type, UObject* Outer) override;
|
||||
|
||||
static OculusXRAnchors::FOculusXRAnchors* GetOculusAnchors();
|
||||
|
||||
FAnchorsXRPtr GetXrAnchors() { return AnchorsXR; }
|
||||
|
||||
private:
|
||||
TArray<IOculusXRCreateAnchorComponent*> CreateComponentInterfaces;
|
||||
OculusXRAnchors::FOculusXRAnchors Anchors;
|
||||
FAnchorsXRPtr AnchorsXR;
|
||||
};
|
||||
|
||||
#else // OCULUS_ANCHORS_SUPPORTED_PLATFORMS
|
||||
|
||||
class FOculusXRAnchorsModule : public FDefaultModuleImpl
|
||||
{
|
||||
};
|
||||
|
||||
#endif // OCULUS_ANCHORS_SUPPORTED_PLATFORMS
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
@@ -0,0 +1,5 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "OculusXRAnchorsModule.h"
|
||||
@@ -0,0 +1,240 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
#include "OculusXRAnchorsUtil.h"
|
||||
#include <khronos/openxr/openxr.h>
|
||||
|
||||
namespace OculusXRAnchors
|
||||
{
|
||||
EOculusXRAnchorResult::Type GetResultFromOVRResult(ovrpResult OVRResult)
|
||||
{
|
||||
switch (OVRResult)
|
||||
{
|
||||
case ovrpSuccess:
|
||||
return EOculusXRAnchorResult::Success;
|
||||
case ovrpWarning_BoundaryVisibilitySuppressionNotAllowed:
|
||||
return EOculusXRAnchorResult::Warning_BoundaryVisibilitySuppressionNotAllowed;
|
||||
|
||||
case ovrpFailure:
|
||||
return EOculusXRAnchorResult::Failure;
|
||||
case ovrpFailure_InvalidParameter:
|
||||
return EOculusXRAnchorResult::Failure_InvalidParameter;
|
||||
case ovrpFailure_NotInitialized:
|
||||
return EOculusXRAnchorResult::Failure_NotInitialized;
|
||||
case ovrpFailure_InvalidOperation:
|
||||
return EOculusXRAnchorResult::Failure_InvalidOperation;
|
||||
case ovrpFailure_Unsupported:
|
||||
return EOculusXRAnchorResult::Failure_Unsupported;
|
||||
case ovrpFailure_NotYetImplemented:
|
||||
return EOculusXRAnchorResult::Failure_NotYetImplemented;
|
||||
case ovrpFailure_OperationFailed:
|
||||
return EOculusXRAnchorResult::Failure_OperationFailed;
|
||||
case ovrpFailure_InsufficientSize:
|
||||
return EOculusXRAnchorResult::Failure_InsufficientSize;
|
||||
case ovrpFailure_DataIsInvalid:
|
||||
return EOculusXRAnchorResult::Failure_DataIsInvalid;
|
||||
case ovrpFailure_DeprecatedOperation:
|
||||
return EOculusXRAnchorResult::Failure_DeprecatedOperation;
|
||||
case ovrpFailure_ErrorLimitReached:
|
||||
return EOculusXRAnchorResult::Failure_ErrorLimitReached;
|
||||
case ovrpFailure_ErrorInitializationFailed:
|
||||
return EOculusXRAnchorResult::Failure_ErrorInitializationFailed;
|
||||
|
||||
// Query Spaces
|
||||
case ovrpFailure_SpaceCloudStorageDisabled:
|
||||
return EOculusXRAnchorResult::Failure_SpaceCloudStorageDisabled;
|
||||
case ovrpFailure_SpaceMappingInsufficient:
|
||||
return EOculusXRAnchorResult::Failure_SpaceMappingInsufficient;
|
||||
case ovrpFailure_SpaceLocalizationFailed:
|
||||
return EOculusXRAnchorResult::Failure_SpaceLocalizationFailed;
|
||||
case ovrpFailure_SpaceNetworkTimeout:
|
||||
return EOculusXRAnchorResult::Failure_SpaceNetworkTimeout;
|
||||
case ovrpFailure_SpaceNetworkRequestFailed:
|
||||
return EOculusXRAnchorResult::Failure_SpaceNetworkRequestFailed;
|
||||
|
||||
// APD
|
||||
case ovrpFailure_SpaceInsufficientResources:
|
||||
return EOculusXRAnchorResult::Failure_SpaceInsufficientResources;
|
||||
case ovrpFailure_SpaceStorageAtCapacity:
|
||||
return EOculusXRAnchorResult::Failure_SpaceStorageAtCapacity;
|
||||
case ovrpFailure_SpaceInsufficientView:
|
||||
return EOculusXRAnchorResult::Failure_SpaceInsufficientView;
|
||||
case ovrpFailure_SpacePermissionInsufficient:
|
||||
return EOculusXRAnchorResult::Failure_SpacePermissionInsufficient;
|
||||
case ovrpFailure_SpaceRateLimited:
|
||||
return EOculusXRAnchorResult::Failure_SpaceRateLimited;
|
||||
case ovrpFailure_SpaceTooDark:
|
||||
return EOculusXRAnchorResult::Failure_SpaceTooDark;
|
||||
case ovrpFailure_SpaceTooBright:
|
||||
return EOculusXRAnchorResult::Failure_SpaceTooBright;
|
||||
|
||||
default:
|
||||
return OVRP_SUCCESS(OVRResult) ? EOculusXRAnchorResult::Success : EOculusXRAnchorResult::Failure;
|
||||
}
|
||||
}
|
||||
|
||||
EOculusXRAnchorResult::Type GetResultFromXrResult(XrResult Result)
|
||||
{
|
||||
switch (Result)
|
||||
{
|
||||
case XR_SUCCESS:
|
||||
return EOculusXRAnchorResult::Success;
|
||||
// case XR_BOUNDARY_VISIBILITY_SUPPRESSION_NOT_ALLOWED_META:
|
||||
// return EOculusXRAnchorResult::Warning_BoundaryVisibilitySuppressionNotAllowed;
|
||||
|
||||
case XR_ERROR_VALIDATION_FAILURE:
|
||||
return EOculusXRAnchorResult::Failure_InvalidParameter;
|
||||
case XR_ERROR_RUNTIME_FAILURE:
|
||||
return EOculusXRAnchorResult::Failure_OperationFailed;
|
||||
case XR_ERROR_FEATURE_UNSUPPORTED:
|
||||
return EOculusXRAnchorResult::Failure_Unsupported;
|
||||
case XR_ERROR_FUNCTION_UNSUPPORTED:
|
||||
return EOculusXRAnchorResult::Failure_NotYetImplemented;
|
||||
case XR_ERROR_SIZE_INSUFFICIENT:
|
||||
return EOculusXRAnchorResult::Failure_InsufficientSize;
|
||||
case XR_ERROR_LIMIT_REACHED:
|
||||
return EOculusXRAnchorResult::Failure_ErrorLimitReached;
|
||||
case XR_ERROR_INITIALIZATION_FAILED:
|
||||
return EOculusXRAnchorResult::Failure_ErrorInitializationFailed;
|
||||
|
||||
// Query Spaces
|
||||
case XR_ERROR_SPACE_CLOUD_STORAGE_DISABLED_FB:
|
||||
return EOculusXRAnchorResult::Failure_SpaceCloudStorageDisabled;
|
||||
case XR_ERROR_SPACE_MAPPING_INSUFFICIENT_FB:
|
||||
return EOculusXRAnchorResult::Failure_SpaceMappingInsufficient;
|
||||
case XR_ERROR_SPACE_LOCALIZATION_FAILED_FB:
|
||||
return EOculusXRAnchorResult::Failure_SpaceLocalizationFailed;
|
||||
case XR_ERROR_SPACE_NETWORK_TIMEOUT_FB:
|
||||
return EOculusXRAnchorResult::Failure_SpaceNetworkTimeout;
|
||||
case XR_ERROR_SPACE_NETWORK_REQUEST_FAILED_FB:
|
||||
return EOculusXRAnchorResult::Failure_SpaceNetworkRequestFailed;
|
||||
|
||||
// APD
|
||||
case XR_ERROR_SPACE_INSUFFICIENT_RESOURCES_META:
|
||||
return EOculusXRAnchorResult::Failure_SpaceInsufficientResources;
|
||||
case XR_ERROR_SPACE_STORAGE_AT_CAPACITY_META:
|
||||
return EOculusXRAnchorResult::Failure_SpaceStorageAtCapacity;
|
||||
case XR_ERROR_SPACE_INSUFFICIENT_VIEW_META:
|
||||
return EOculusXRAnchorResult::Failure_SpaceInsufficientView;
|
||||
case XR_ERROR_SPACE_PERMISSION_INSUFFICIENT_META:
|
||||
return EOculusXRAnchorResult::Failure_SpacePermissionInsufficient;
|
||||
case XR_ERROR_SPACE_RATE_LIMITED_META:
|
||||
return EOculusXRAnchorResult::Failure_SpaceRateLimited;
|
||||
case XR_ERROR_SPACE_TOO_DARK_META:
|
||||
return EOculusXRAnchorResult::Failure_SpaceTooDark;
|
||||
case XR_ERROR_SPACE_TOO_BRIGHT_META:
|
||||
return EOculusXRAnchorResult::Failure_SpaceTooBright;
|
||||
|
||||
default:
|
||||
return XR_SUCCEEDED(Result) ? EOculusXRAnchorResult::Success : EOculusXRAnchorResult::Failure;
|
||||
}
|
||||
}
|
||||
|
||||
EOculusXRSpaceComponentType ToComponentType(XrSpaceComponentTypeFB XrType)
|
||||
{
|
||||
switch (XrType)
|
||||
{
|
||||
case XR_SPACE_COMPONENT_TYPE_LOCATABLE_FB:
|
||||
return EOculusXRSpaceComponentType::Locatable;
|
||||
case XR_SPACE_COMPONENT_TYPE_STORABLE_FB:
|
||||
return EOculusXRSpaceComponentType::Storable;
|
||||
case XR_SPACE_COMPONENT_TYPE_SHARABLE_FB:
|
||||
return EOculusXRSpaceComponentType::Sharable;
|
||||
case XR_SPACE_COMPONENT_TYPE_BOUNDED_2D_FB:
|
||||
return EOculusXRSpaceComponentType::ScenePlane;
|
||||
case XR_SPACE_COMPONENT_TYPE_BOUNDED_3D_FB:
|
||||
return EOculusXRSpaceComponentType::SceneVolume;
|
||||
case XR_SPACE_COMPONENT_TYPE_SEMANTIC_LABELS_FB:
|
||||
return EOculusXRSpaceComponentType::SemanticClassification;
|
||||
case XR_SPACE_COMPONENT_TYPE_ROOM_LAYOUT_FB:
|
||||
return EOculusXRSpaceComponentType::RoomLayout;
|
||||
case XR_SPACE_COMPONENT_TYPE_SPACE_CONTAINER_FB:
|
||||
return EOculusXRSpaceComponentType::SpaceContainer;
|
||||
case XR_SPACE_COMPONENT_TYPE_TRIANGLE_MESH_META:
|
||||
return EOculusXRSpaceComponentType::TriangleMesh;
|
||||
default:
|
||||
return EOculusXRSpaceComponentType::Undefined;
|
||||
}
|
||||
}
|
||||
|
||||
XrSpaceComponentTypeFB ToComponentType(EOculusXRSpaceComponentType ComponentType)
|
||||
{
|
||||
switch (ComponentType)
|
||||
{
|
||||
case EOculusXRSpaceComponentType::Locatable:
|
||||
return XR_SPACE_COMPONENT_TYPE_LOCATABLE_FB;
|
||||
case EOculusXRSpaceComponentType::Storable:
|
||||
return XR_SPACE_COMPONENT_TYPE_STORABLE_FB;
|
||||
case EOculusXRSpaceComponentType::Sharable:
|
||||
return XR_SPACE_COMPONENT_TYPE_SHARABLE_FB;
|
||||
case EOculusXRSpaceComponentType::ScenePlane:
|
||||
return XR_SPACE_COMPONENT_TYPE_BOUNDED_2D_FB;
|
||||
case EOculusXRSpaceComponentType::SceneVolume:
|
||||
return XR_SPACE_COMPONENT_TYPE_BOUNDED_3D_FB;
|
||||
case EOculusXRSpaceComponentType::SemanticClassification:
|
||||
return XR_SPACE_COMPONENT_TYPE_SEMANTIC_LABELS_FB;
|
||||
case EOculusXRSpaceComponentType::RoomLayout:
|
||||
return XR_SPACE_COMPONENT_TYPE_ROOM_LAYOUT_FB;
|
||||
case EOculusXRSpaceComponentType::SpaceContainer:
|
||||
return XR_SPACE_COMPONENT_TYPE_SPACE_CONTAINER_FB;
|
||||
case EOculusXRSpaceComponentType::TriangleMesh:
|
||||
return XR_SPACE_COMPONENT_TYPE_TRIANGLE_MESH_META;
|
||||
default:
|
||||
return XR_SPACE_COMPONENT_TYPE_MAX_ENUM_FB;
|
||||
}
|
||||
}
|
||||
|
||||
EOculusXRSpaceStorageLocation ToStorageLocation(XrSpaceStorageLocationFB XrStorageLocation)
|
||||
{
|
||||
switch (XrStorageLocation)
|
||||
{
|
||||
case XR_SPACE_STORAGE_LOCATION_LOCAL_FB:
|
||||
return EOculusXRSpaceStorageLocation::Local;
|
||||
case XR_SPACE_STORAGE_LOCATION_CLOUD_FB:
|
||||
return EOculusXRSpaceStorageLocation::Cloud;
|
||||
default:
|
||||
return EOculusXRSpaceStorageLocation::Invalid;
|
||||
}
|
||||
}
|
||||
|
||||
XrSpaceStorageLocationFB ToStorageLocation(EOculusXRSpaceStorageLocation StorageLocation)
|
||||
{
|
||||
switch (StorageLocation)
|
||||
{
|
||||
case EOculusXRSpaceStorageLocation::Local:
|
||||
return XR_SPACE_STORAGE_LOCATION_LOCAL_FB;
|
||||
case EOculusXRSpaceStorageLocation::Cloud:
|
||||
return XR_SPACE_STORAGE_LOCATION_CLOUD_FB;
|
||||
default:
|
||||
return XR_SPACE_STORAGE_LOCATION_INVALID_FB;
|
||||
}
|
||||
}
|
||||
|
||||
FOculusXRUUID ToUuid(const XrUuidEXT& XrUuid)
|
||||
{
|
||||
return FOculusXRUUID(XrUuid.data);
|
||||
}
|
||||
|
||||
XrUuidEXT ToUuid(const FOculusXRUUID& Uuid)
|
||||
{
|
||||
XrUuidEXT result;
|
||||
FMemory::Memcpy(result.data, Uuid.UUIDBytes);
|
||||
return result;
|
||||
}
|
||||
|
||||
FString GetStringFromResult(EOculusXRAnchorResult::Type Result)
|
||||
{
|
||||
return UEnum::GetDisplayValueAsText(Result).ToString();
|
||||
}
|
||||
|
||||
FString ToString(EOculusXRSpaceComponentType ComponentType)
|
||||
{
|
||||
// Todo: More performant to use const strings and a case statement?
|
||||
return UEnum::GetDisplayValueAsText(ComponentType).ToString();
|
||||
}
|
||||
|
||||
FString ToString(EOculusXRSpaceStorageLocation StorageLocation)
|
||||
{
|
||||
// Todo: More performant to use const strings and a case statement?
|
||||
return UEnum::GetDisplayValueAsText(StorageLocation).ToString();
|
||||
}
|
||||
} // namespace OculusXRAnchors
|
||||
@@ -0,0 +1,26 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "openxr/OculusXRAnchorsXRIncludes.h"
|
||||
#include "OculusXRAnchorTypes.h"
|
||||
#include "OculusXRHMDPrivate.h"
|
||||
|
||||
namespace OculusXRAnchors
|
||||
{
|
||||
OCULUSXRANCHORS_API EOculusXRAnchorResult::Type GetResultFromOVRResult(ovrpResult OVRResult);
|
||||
OCULUSXRANCHORS_API EOculusXRAnchorResult::Type GetResultFromXrResult(XrResult Result);
|
||||
|
||||
OCULUSXRANCHORS_API EOculusXRSpaceComponentType ToComponentType(XrSpaceComponentTypeFB XrComponentType);
|
||||
OCULUSXRANCHORS_API XrSpaceComponentTypeFB ToComponentType(EOculusXRSpaceComponentType ComponentType);
|
||||
|
||||
OCULUSXRANCHORS_API EOculusXRSpaceStorageLocation ToStorageLocation(XrSpaceStorageLocationFB XrStorageLocation);
|
||||
OCULUSXRANCHORS_API XrSpaceStorageLocationFB ToStorageLocation(EOculusXRSpaceStorageLocation StorageLocation);
|
||||
|
||||
OCULUSXRANCHORS_API FOculusXRUUID ToUuid(const XrUuidEXT& XrUuid);
|
||||
OCULUSXRANCHORS_API XrUuidEXT ToUuid(const FOculusXRUUID& Uuid);
|
||||
|
||||
OCULUSXRANCHORS_API FString GetStringFromResult(EOculusXRAnchorResult::Type Result);
|
||||
OCULUSXRANCHORS_API FString ToString(EOculusXRSpaceComponentType ComponentType);
|
||||
OCULUSXRANCHORS_API FString ToString(EOculusXRSpaceStorageLocation StorageLocation);
|
||||
} // namespace OculusXRAnchors
|
||||
@@ -0,0 +1,28 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
#include "OculusXRSpatialAnchorComponent.h"
|
||||
|
||||
DEFINE_LOG_CATEGORY(LogOculusSpatialAnchor);
|
||||
|
||||
UOculusXRSpatialAnchorComponent::UOculusXRSpatialAnchorComponent(const FObjectInitializer& ObjectInitializer)
|
||||
: Super(ObjectInitializer)
|
||||
{
|
||||
}
|
||||
|
||||
bool UOculusXRSpatialAnchorComponent::Create(const FTransform& NewAnchorTransform, AActor* OwningActor, const FOculusXRSpatialAnchorCreateDelegate& Callback)
|
||||
{
|
||||
EOculusXRAnchorResult::Type AnchorResult;
|
||||
return OculusXRAnchors::FOculusXRAnchors::CreateSpatialAnchor(NewAnchorTransform, OwningActor, Callback, AnchorResult);
|
||||
}
|
||||
|
||||
bool UOculusXRSpatialAnchorComponent::Erase(const FOculusXRAnchorEraseDelegate& Callback)
|
||||
{
|
||||
EOculusXRAnchorResult::Type AnchorResult;
|
||||
return OculusXRAnchors::FOculusXRAnchors::EraseAnchor(this, Callback, AnchorResult);
|
||||
}
|
||||
|
||||
bool UOculusXRSpatialAnchorComponent::Save(EOculusXRSpaceStorageLocation Location, const FOculusXRAnchorSaveDelegate& Callback)
|
||||
{
|
||||
EOculusXRAnchorResult::Type AnchorResult;
|
||||
return OculusXRAnchors::FOculusXRAnchors::SaveAnchor(this, Location, Callback, AnchorResult);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
#include "OculusXRSpatialAnchorManager.h"
|
||||
#include "OculusXRAnchorBPFunctionLibrary.h"
|
||||
|
||||
namespace OculusXRAnchors
|
||||
{
|
||||
bool FOculusXRSpatialAnchorManager::CreateSpatialAnchor(const FTransform& InTransform, uint64& OutRequestId)
|
||||
{
|
||||
EOculusXRAnchorResult::Type Result = CreateAnchor(InTransform, OutRequestId, FTransform::Identity);
|
||||
return UOculusXRAnchorBPFunctionLibrary::IsAnchorResultSuccess(Result);
|
||||
}
|
||||
} // namespace OculusXRAnchors
|
||||
@@ -0,0 +1,19 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "OculusXRAnchorManager.h"
|
||||
|
||||
namespace OculusXRAnchors
|
||||
{
|
||||
struct FOculusXRSpatialAnchorManager : FOculusXRAnchorManager
|
||||
{
|
||||
FOculusXRSpatialAnchorManager()
|
||||
: FOculusXRAnchorManager()
|
||||
{
|
||||
}
|
||||
|
||||
static bool CreateSpatialAnchor(const FTransform& InTransform, uint64& OutRequestId);
|
||||
};
|
||||
} // namespace OculusXRAnchors
|
||||
@@ -0,0 +1,24 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "OculusXRTelemetry.h"
|
||||
|
||||
namespace OculusXRTelemetry::Events
|
||||
{
|
||||
using FAnchorsCreate = TMarker<191967648>;
|
||||
using FAnchorsCreateRequest = TScopedMarker<FAnchorsCreate, EScopeMode::Start>;
|
||||
using FAnchorsCreateResponse = TScopedMarker<FAnchorsCreate, EScopeMode::End>;
|
||||
using FAnchorsSetComponentStatus = TMarker<191962330>;
|
||||
using FAnchorsSetComponentStatusRequest = TScopedMarker<FAnchorsSetComponentStatus, EScopeMode::Start>;
|
||||
using FAnchorsSetComponentStatusResponse = TScopedMarker<FAnchorsSetComponentStatus, EScopeMode::End>;
|
||||
using FAnchorsSave = TMarker<191961984>;
|
||||
using FAnchorsSaveRequest = TScopedMarker<FAnchorsSave, EScopeMode::Start>;
|
||||
using FAnchorsSaveResponse = TScopedMarker<FAnchorsSave, EScopeMode::End>;
|
||||
using FAnchorsQuery = TMarker<191959258>;
|
||||
using FAnchorsQueryRequest = TScopedMarker<FAnchorsQuery, EScopeMode::Start>;
|
||||
using FAnchorsQueryResponse = TScopedMarker<FAnchorsQuery, EScopeMode::End>;
|
||||
using FAnchorsErase = TMarker<191960591>;
|
||||
using FAnchorsEraseRequest = TScopedMarker<FAnchorsErase, EScopeMode::Start>;
|
||||
using FAnchorsEraseResponse = TScopedMarker<FAnchorsErase, EScopeMode::End>;
|
||||
} // namespace OculusXRTelemetry::Events
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,110 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "OculusXRAnchorsXRIncludes.h"
|
||||
#include "IOpenXRExtensionPlugin.h"
|
||||
#include "OculusXRAnchorTypes.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "OculusXRAnchors"
|
||||
|
||||
class FOpenXRHMD;
|
||||
|
||||
namespace XRAnchors
|
||||
{
|
||||
extern PFN_xrCreateSpatialAnchorFB xrCreateSpatialAnchorFB;
|
||||
extern PFN_xrSetSpaceComponentStatusFB xrSetSpaceComponentStatusFB;
|
||||
extern PFN_xrGetSpaceComponentStatusFB xrGetSpaceComponentStatusFB;
|
||||
extern PFN_xrEnumerateSpaceSupportedComponentsFB xrEnumerateSpaceSupportedComponentsFB;
|
||||
extern PFN_xrGetSpaceUuidFB xrGetSpaceUuidFB;
|
||||
extern PFN_xrGetSpaceContainerFB xrGetSpaceContainerFB;
|
||||
extern PFN_xrQuerySpacesFB xrQuerySpacesFB;
|
||||
extern PFN_xrRetrieveSpaceQueryResultsFB xrRetrieveSpaceQueryResultsFB;
|
||||
extern PFN_xrShareSpacesFB xrShareSpacesFB;
|
||||
extern PFN_xrShareSpacesMETA xrShareSpacesMETA;
|
||||
extern PFN_xrSaveSpaceFB xrSaveSpaceFB;
|
||||
extern PFN_xrEraseSpaceFB xrEraseSpaceFB;
|
||||
extern PFN_xrSaveSpaceListFB xrSaveSpaceListFB;
|
||||
extern PFN_xrCreateSpaceUserFB xrCreateSpaceUserFB;
|
||||
extern PFN_xrDestroySpaceUserFB xrDestroySpaceUserFB;
|
||||
extern PFN_xrGetSpaceUserIdFB xrGetSpaceUserIdFB;
|
||||
extern PFN_xrSaveSpacesMETA xrSaveSpacesMETA;
|
||||
extern PFN_xrEraseSpacesMETA xrEraseSpacesMETA;
|
||||
extern PFN_xrDiscoverSpacesMETA xrDiscoverSpacesMETA;
|
||||
extern PFN_xrRetrieveSpaceDiscoveryResultsMETA xrRetrieveSpaceDiscoveryResultsMETA;
|
||||
|
||||
class FAnchorsXR : public IOpenXRExtensionPlugin
|
||||
{
|
||||
public:
|
||||
// IOculusXROpenXRHMDPlugin
|
||||
virtual bool GetRequiredExtensions(TArray<const ANSICHAR*>& OutExtensions) override;
|
||||
virtual bool GetOptionalExtensions(TArray<const ANSICHAR*>& OutExtensions) override;
|
||||
virtual const void* OnCreateInstance(class IOpenXRHMDModule* InModule, const void* InNext) override;
|
||||
virtual const void* OnCreateSession(XrInstance InInstance, XrSystemId InSystem, const void* InNext) override;
|
||||
virtual void OnDestroySession(XrSession InSession) override;
|
||||
virtual void OnEvent(XrSession InSession, const XrEventDataBaseHeader* InHeader) override;
|
||||
|
||||
public:
|
||||
FAnchorsXR();
|
||||
virtual ~FAnchorsXR();
|
||||
void RegisterAsOpenXRExtension();
|
||||
|
||||
bool IsAnchorExtensionSupported() const { return bExtAnchorsEnabled; }
|
||||
bool IsContainerExtensionSupported() const { return bExtContainerEnabled; }
|
||||
bool IsQueryExtensionSupported() const { return bExtQueryEnabled; }
|
||||
bool IsSharingExtensionSupported() const { return bExtSharingEnabled; }
|
||||
bool IsStorageExtensionSupported() const { return bExtStorageEnabled; }
|
||||
bool IsStorageBatchExtensionSupported() const { return bExtStorageBatchEnabled; }
|
||||
bool IsUserExtensionSupported() const { return bExtUserEnabled; }
|
||||
bool IsDiscoveryExtensionSupported() const { return bExtDiscoveryEnabled; }
|
||||
bool IsPersistenceExtensionSupported() const { return bExtPersistenceEnabled; }
|
||||
bool IsSharingMetaExtensionSupported() const { return bExtSharingMetaEnabled; }
|
||||
bool IsGroupSharingExtensionSupported() const { return bExtGroupSharingEnabled; }
|
||||
|
||||
XrResult CreateSpatialAnchor(const FTransform& InTransform, uint64& OutRequestId, const FTransform& CameraTransform);
|
||||
XrResult DestroySpatialAnchor(uint64 AnchorHandle);
|
||||
|
||||
XrResult TryGetAnchorTransform(uint64 AnchorHandle, FTransform& OutTransform, FOculusXRAnchorLocationFlags& OutLocationFlags, EOculusXRAnchorSpace Space);
|
||||
XrResult SetAnchorComponentStatus(uint64 AnchorHandle, EOculusXRSpaceComponentType ComponentType, bool Enable, float Timeout, uint64& OutRequestId);
|
||||
XrResult GetAnchorComponentStatus(uint64 AnchorHandle, EOculusXRSpaceComponentType ComponentType, bool& OutEnabled, bool& OutChangePending);
|
||||
XrResult GetSupportedAnchorComponents(uint64 AnchorHandle, TArray<EOculusXRSpaceComponentType>& OutSupportedTypes);
|
||||
XrResult GetAnchorContainerUUIDs(uint64 AnchorHandle, TArray<FOculusXRUUID>& OutUUIDs);
|
||||
|
||||
XrResult SaveAnchor(uint64 AnchorHandle, EOculusXRSpaceStorageLocation StorageLocation, EOculusXRSpaceStoragePersistenceMode StoragePersistenceMode, uint64& OutRequestId);
|
||||
XrResult SaveAnchorList(const TArray<uint64>& AnchorHandles, EOculusXRSpaceStorageLocation StorageLocation, uint64& OutRequestId);
|
||||
XrResult SaveAnchors(const TArray<uint64>& AnchorHandles, uint64& OutRequestId);
|
||||
|
||||
XrResult DiscoverAnchors(const FOculusXRSpaceDiscoveryInfo& DiscoveryInfo, uint64& OutRequestId);
|
||||
XrResult QueryAnchors(const FOculusXRSpaceQueryInfo& QueryInfo, uint64& OutRequestId);
|
||||
|
||||
XrResult ShareAnchors(const TArray<uint64>& AnchorHandles, const TArray<uint64>& UserIds, uint64& OutRequestId);
|
||||
XrResult ShareAnchorsWithGroups(const TArray<uint64>& AnchorHandles, const TArray<FOculusXRUUID>& Groups, uint64& OutRequestId);
|
||||
|
||||
XrResult CreateSpaceUser(uint64 SpaceUserId, SpaceUser& OutUser);
|
||||
XrResult GetSpaceUserId(const SpaceUser& User, uint64& OutId);
|
||||
XrResult DestroySpaceUser(const SpaceUser& User);
|
||||
|
||||
XrResult EraseAnchor(uint64 AnchorHandle, EOculusXRSpaceStorageLocation StorageLocation, uint64& OutRequestId);
|
||||
XrResult EraseAnchors(const TArray<FOculusXRUInt64>& AnchorHandles, const TArray<FOculusXRUUID>& UUIDs, uint64& OutRequestId);
|
||||
|
||||
private:
|
||||
void InitOpenXRFunctions(XrInstance InInstance);
|
||||
|
||||
bool bExtAnchorsEnabled;
|
||||
bool bExtContainerEnabled;
|
||||
bool bExtQueryEnabled;
|
||||
bool bExtSharingEnabled;
|
||||
bool bExtStorageEnabled;
|
||||
bool bExtStorageBatchEnabled;
|
||||
bool bExtUserEnabled;
|
||||
bool bExtDiscoveryEnabled;
|
||||
bool bExtPersistenceEnabled;
|
||||
bool bExtSharingMetaEnabled;
|
||||
bool bExtGroupSharingEnabled;
|
||||
|
||||
FOpenXRHMD* OpenXRHMD;
|
||||
};
|
||||
|
||||
} // namespace XRAnchors
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
@@ -0,0 +1,9 @@
|
||||
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <khronos/openxr/openxr.h>
|
||||
#include <khronos/openxr/meta_openxr_preview/meta_spatial_entity_discovery.h>
|
||||
#include <khronos/openxr/meta_openxr_preview/meta_spatial_entity_persistence.h>
|
||||
#include <khronos/openxr/meta_openxr_preview/meta_spatial_entity_sharing.h>
|
||||
#include <khronos/openxr/meta_openxr_preview/meta_spatial_entity_group_sharing.h>
|
||||
Reference in New Issue
Block a user