Android build settings + metaxr

This commit is contained in:
2025-05-14 14:00:02 +03:00
parent 6a2bb7475e
commit d5aa21f55c
594 changed files with 200530 additions and 2 deletions

View File

@@ -0,0 +1,49 @@
// @lint-ignore-every LICENSELINT
// Copyright Epic Games, Inc. All Rights Reserved.
namespace UnrealBuildTool.Rules
{
public class OculusXRColocation : ModuleRules
{
public OculusXRColocation(ReadOnlyTargetRules Target) : base(Target)
{
bUseUnity = true;
PrivateDependencyModuleNames.AddRange(
new string[]
{
"Core",
"CoreUObject",
"Engine",
"HeadMountedDisplay",
"OculusXRHMD",
"OVRPluginXR",
"XRBase",
"OpenXR",
"OpenXRHMD",
"OculusXRAnchors",
"OculusXRAsyncRequest"
});
PublicDependencyModuleNames.AddRange(
new string[]
{
"OculusXRAsyncRequest",
"KhronosOpenXRHeaders",
});
PrivateIncludePaths.AddRange(
new string[] {
"OculusXRHMD/Private",
"OculusXRAnchors/Private",
});
PublicIncludePaths.AddRange(
new string[] {
"Runtime/Engine/Classes/Components",
});
AddEngineThirdPartyPrivateStaticDependencies(Target, "OpenXR");
}
}
}

View File

@@ -0,0 +1,52 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
#include "OculusXRColocation.h"
#include "OculusXRColocationModule.h"
#include "OculusXRColocationTypes.h"
#include "OculusXRColocationUtil.h"
#include "OculusXRAsyncRequestSystem.h"
#include "OculusXRHMDModule.h"
namespace OculusXRColocation
{
TSharedPtr<FDiscoverSessionsRequest> FColocation::DiscoverSessionsAsync(const FDiscoverSessionsRequest::FCompleteDelegate& OnComplete, const FOculusXRColocationSessionFoundDelegate& OnSessionFound)
{
auto request = OculusXR::FAsyncRequestSystem::CreateRequest<FDiscoverSessionsRequest>();
request->BindOnComplete(OnComplete);
request->BindOnSessionFound(OnSessionFound);
request->Execute();
return request;
}
EColocationResult FColocation::StopDiscoverSessions(TSharedPtr<FDiscoverSessionsRequest> Request)
{
uint64 requestId = Request->GetRequestId().Id;
ovrpResult result = FOculusXRHMDModule::GetPluginWrapper().StopColocationDiscovery(&requestId);
UE_LOG(LogOculusXRColocation, Log, TEXT("Stopping colocation session discovery. RequestID: %llu, Launch async result: %d"), Request->GetRequestId().Id, result);
EColocationResult colocationResult = GetResult(result);
if (colocationResult != EColocationResult::Success)
{
UE_LOG(LogOculusXRColocation, Warning, TEXT("Failed to stop local group discovery."));
}
return colocationResult;
}
TSharedPtr<FStartSessionAdvertisementRequest> FColocation::StartSessionAdvertisementAsync(const TArray<uint8>& SessionData, const FStartSessionAdvertisementRequest::FCompleteDelegate& OnComplete)
{
auto request = OculusXR::FAsyncRequestSystem::CreateRequest<FStartSessionAdvertisementRequest>(SessionData);
request->BindOnComplete(OnComplete);
request->Execute();
return request;
}
TSharedPtr<FStopSessionAdvertisementRequest> FColocation::StopSessionAdvertisementAsync(const FStopSessionAdvertisementRequest::FCompleteDelegate& OnComplete)
{
auto request = OculusXR::FAsyncRequestSystem::CreateRequest<FStopSessionAdvertisementRequest>();
request->BindOnComplete(OnComplete);
request->Execute();
return request;
}
} // namespace OculusXRColocation

View File

@@ -0,0 +1,12 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
#include "OculusXRColocationEventDelegates.h"
FOculusXRColocationEventDelegates::FStartColocationAdvertisementComplete FOculusXRColocationEventDelegates::StartColocationAdvertisementComplete;
FOculusXRColocationEventDelegates::FStopColocationAdvertisementComplete FOculusXRColocationEventDelegates::StopColocationAdvertisementComplete;
FOculusXRColocationEventDelegates::FColocationAdvertisementComplete FOculusXRColocationEventDelegates::ColocationAdvertisementComplete;
FOculusXRColocationEventDelegates::FStartColocationDiscoveryComplete FOculusXRColocationEventDelegates::StartColocationDiscoveryComplete;
FOculusXRColocationEventDelegates::FStopColocationDiscoveryComplete FOculusXRColocationEventDelegates::StopColocationDiscoveryComplete;
FOculusXRColocationEventDelegates::FColocationDiscoveryComplete FOculusXRColocationEventDelegates::ColocationDiscoveryComplete;
FOculusXRColocationEventDelegates::FColocationDiscoveryResultAvailable FOculusXRColocationEventDelegates::ColocationDiscoveryResultAvailable;

View File

@@ -0,0 +1,32 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
#pragma once
#include "CoreTypes.h"
#include "OculusXRColocationTypes.h"
#include "Delegates/Delegate.h"
class FOculusXRColocationEventDelegates
{
public:
DECLARE_MULTICAST_DELEGATE_ThreeParams(FStartColocationAdvertisementComplete, FOculusXRUInt64 /*requestId*/, FOculusXRUUID /*uuid*/, EColocationResult /*result*/);
static OCULUSXRCOLOCATION_API FStartColocationAdvertisementComplete StartColocationAdvertisementComplete;
DECLARE_MULTICAST_DELEGATE_TwoParams(FColocationAdvertisementComplete, FOculusXRUInt64 /*requestId*/, EColocationResult /*result*/);
static OCULUSXRCOLOCATION_API FColocationAdvertisementComplete ColocationAdvertisementComplete;
DECLARE_MULTICAST_DELEGATE_TwoParams(FStopColocationAdvertisementComplete, FOculusXRUInt64 /*requestId*/, EColocationResult /*result*/);
static OCULUSXRCOLOCATION_API FStopColocationAdvertisementComplete StopColocationAdvertisementComplete;
DECLARE_MULTICAST_DELEGATE_TwoParams(FStartColocationDiscoveryComplete, FOculusXRUInt64 /*requestId*/, EColocationResult /*result*/);
static OCULUSXRCOLOCATION_API FStartColocationDiscoveryComplete StartColocationDiscoveryComplete;
DECLARE_MULTICAST_DELEGATE_TwoParams(FColocationDiscoveryComplete, FOculusXRUInt64 /*requestId*/, EColocationResult /*result*/);
static OCULUSXRCOLOCATION_API FColocationDiscoveryComplete ColocationDiscoveryComplete;
DECLARE_MULTICAST_DELEGATE_TwoParams(FStopColocationDiscoveryComplete, FOculusXRUInt64 /*requestId*/, EColocationResult /*result*/);
static OCULUSXRCOLOCATION_API FStopColocationDiscoveryComplete StopColocationDiscoveryComplete;
DECLARE_MULTICAST_DELEGATE_ThreeParams(FColocationDiscoveryResultAvailable, FOculusXRUInt64 /*requestId*/, FOculusXRUUID /*resultUuid*/, const TArray<uint8>& /*metadata*/);
static OCULUSXRCOLOCATION_API FColocationDiscoveryResultAvailable ColocationDiscoveryResultAvailable;
};

View File

@@ -0,0 +1,127 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
#include "OculusXRColocationEventPolling.h"
#include "OculusXRColocationModule.h"
#include "OculusXRColocationRequests.h"
#include "OculusXRColocationSubsystem.h"
#include "OculusXRColocationUtil.h"
#include "OculusXRColocationEventDelegates.h"
#include "OculusXRHMDPrivate.h"
#include "OculusXRHMDModule.h"
#include "Engine/Engine.h"
namespace OculusXRColocation
{
template <typename T>
void GetEventDataAs(ovrpEventDataBuffer& Buffer, T& OutEventData)
{
memcpy(&OutEventData, reinterpret_cast<uint8*>(&Buffer), sizeof(T));
}
void FColocationEventPolling::OnPollEvent(ovrpEventDataBuffer* EventDataBuffer, bool& EventPollResult)
{
ovrpEventDataBuffer& buf = *EventDataBuffer;
EventPollResult = true;
switch (buf.EventType)
{
case ovrpEventType_StartColocationAdvertisementComplete:
{
ovrpEventStartColocationAdvertisementComplete eventData;
GetEventDataAs(buf, eventData);
UE_LOG(LogOculusXRColocation, Log, TEXT("ovrpEventStartColocationAdvertisementComplete: Request ID: %llu -- SessionUuid: %s -- Result: %s"),
eventData.AdvertisementRequestId,
*FOculusXRUUID(eventData.AdvertisementUuid.data).ToString(),
*ToString(GetResult(eventData.Result)));
FOculusXRColocationEventDelegates::StartColocationAdvertisementComplete.Broadcast(eventData.AdvertisementRequestId, eventData.AdvertisementUuid.data, GetResult(eventData.Result));
break;
}
case ovrpEventType_ColocationAdvertisementComplete:
{
ovrpEventColocationAdvertisementComplete eventData;
GetEventDataAs(buf, eventData);
UE_LOG(LogOculusXRColocation, Log, TEXT("ovrpEventColocationAdvertisementComplete: Request ID: %llu -- Result: %s"),
eventData.AdvertisementRequestId,
*ToString(GetResult(eventData.Result)));
FOculusXRColocationEventDelegates::ColocationAdvertisementComplete.Broadcast(eventData.AdvertisementRequestId, GetResult(eventData.Result));
break;
}
case ovrpEventType_StopColocationAdvertisementComplete:
{
ovrpEventStopColocationAdvertisementComplete eventData;
GetEventDataAs(buf, eventData);
FOculusXRColocationEventDelegates::StopColocationAdvertisementComplete.Broadcast(eventData.RequestId, GetResult(eventData.Result));
break;
}
case ovrpEventType_StartColocationDiscoveryComplete:
{
ovrpEventStartColocationDiscoveryComplete eventData;
GetEventDataAs(buf, eventData);
UE_LOG(LogOculusXRColocation, Log, TEXT("ovrpEventStartColocationDiscoveryComplete: Request ID: %llu -- Result: %s"),
eventData.DiscoveryRequestId,
*ToString(GetResult(eventData.Result)));
FOculusXRColocationEventDelegates::StartColocationDiscoveryComplete.Broadcast(eventData.DiscoveryRequestId, GetResult(eventData.Result));
break;
}
case ovrpEventType_ColocationDiscoveryResult:
{
ovrpEventColocationDiscoveryResult eventData;
GetEventDataAs(buf, eventData);
UE_LOG(LogOculusXRColocation, Log, TEXT("ovrpEventColocationDiscoveryResult: Request ID: %llu -- FoundSessionUuid: %s"),
eventData.DiscoveryRequestId,
*FOculusXRUUID(eventData.AdvertisementUuid.data).ToString());
TArray<uint8> metaData(eventData.Buffer, eventData.BufferSize);
FOculusXRColocationEventDelegates::ColocationDiscoveryResultAvailable.Broadcast(eventData.DiscoveryRequestId, eventData.AdvertisementUuid.data, metaData);
break;
}
case ovrpEventType_ColocationDiscoveryComplete:
{
ovrpEventColocationDiscoveryComplete eventData;
GetEventDataAs(buf, eventData);
UE_LOG(LogOculusXRColocation, Log, TEXT("ovrpEventColocationDiscoveryComplete: Request ID: %llu -- Result: %s"),
eventData.DiscoveryRequestId,
*ToString(GetResult(eventData.Result)));
FOculusXRColocationEventDelegates::ColocationDiscoveryComplete.Broadcast(eventData.DiscoveryRequestId, GetResult(eventData.Result));
break;
}
case ovrpEventType_StopColocationDiscoveryComplete:
{
ovrpEventStopColocationDiscoveryComplete eventData;
GetEventDataAs(buf, eventData);
UE_LOG(LogOculusXRColocation, Log, TEXT("ovrpEventType_StopColocationDiscoveryComplete: Request ID: %llu -- Result: %s"),
eventData.RequestId,
*ToString(GetResult(eventData.Result)));
FOculusXRColocationEventDelegates::ColocationDiscoveryComplete.Broadcast(eventData.RequestId, GetResult(eventData.Result));
// no-op
break;
}
default:
{
EventPollResult = false;
return;
}
}
}
} // namespace OculusXRColocation

View File

@@ -0,0 +1,14 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
#pragma once
#include "OculusXRPluginWrapper.h"
namespace OculusXRColocation
{
struct FColocationEventPolling
{
public:
static void OnPollEvent(ovrpEventDataBuffer* EventDataBuffer, bool& EventPollResult);
};
} // namespace OculusXRColocation

View File

@@ -0,0 +1,18 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
#include "OculusXRColocationFunctionLibrary.h"
#include "OculusXRColocationModule.h"
#include "OculusXRColocationSubsystem.h"
#include "OculusXRColocation.h"
void UOculusXRColocationFunctionLibrary::StopColocationSessionDiscovery()
{
auto request = UOculusXRColocationSubsystem::Get()->GetDiscoveryRequest();
if (!request.IsValid())
{
UE_LOG(LogOculusXRColocation, Warning, TEXT("Attempted to stop colocation session discovery but there is no active discovery request!"));
return;
}
OculusXRColocation::FColocation::StopDiscoverSessions(request);
}

View File

@@ -0,0 +1,28 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
#include "OculusXRColocationFunctions.h"
#include "OculusXRColocationFunctionsOVR.h"
#include "OculusXRColocationFunctionsOpenXR.h"
#include "IOpenXRHMD.h"
#include "OculusXRHMD.h"
TSharedPtr<IOculusXRColocationFunctions> IOculusXRColocationFunctions::ColocationFunctionsImpl = nullptr;
TSharedPtr<IOculusXRColocationFunctions> IOculusXRColocationFunctions::GetOculusXRColocationFunctionsImpl()
{
if (ColocationFunctionsImpl == nullptr)
{
const FName SystemName(TEXT("OpenXR"));
const bool IsOpenXR = GEngine->XRSystem.IsValid() && (GEngine->XRSystem->GetSystemName() == SystemName);
if (OculusXRHMD::FOculusXRHMD::GetOculusXRHMD() != nullptr)
{
ColocationFunctionsImpl = MakeShared<FOculusXRColocationFunctionsOVR>();
}
else if (IsOpenXR)
{
ColocationFunctionsImpl = MakeShared<FOculusXRColocationFunctionsOpenXR>();
}
}
check(ColocationFunctionsImpl);
return ColocationFunctionsImpl;
}

View File

@@ -0,0 +1,18 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
#pragma once
#include "OculusXRColocationTypes.h"
class OCULUSXRCOLOCATION_API IOculusXRColocationFunctions
{
public:
virtual EColocationResult StartColocationDiscovery(uint64& OutRequestId) = 0;
virtual EColocationResult StopColocationDiscovery(uint64& OutRequestId) = 0;
virtual EColocationResult StartColocationAdvertisement(const TArray<uint8>& MetaData, uint64& OutRequestId) = 0;
virtual EColocationResult StopColocationAdvertisement(uint64& OutRequestId) = 0;
static TSharedPtr<IOculusXRColocationFunctions> GetOculusXRColocationFunctionsImpl();
static TSharedPtr<IOculusXRColocationFunctions> ColocationFunctionsImpl;
};

View File

@@ -0,0 +1,54 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
#include "OculusXRColocationFunctionsOVR.h"
#include "OculusXRHMD.h"
#include "OculusXRColocationUtil.h"
#include "OculusXRColocationModule.h"
EColocationResult FOculusXRColocationFunctionsOVR::StartColocationDiscovery(uint64& OutRequestId)
{
ovrpResult result = FOculusXRHMDModule::GetPluginWrapper().StartColocationDiscovery(&OutRequestId);
auto ueResult = OculusXRColocation::GetResult(result);
UE_LOG(LogOculusXRColocation, Log, TEXT("[OVR::StartColocationDiscovery] RequestID: %llu, Launch async result: %s"),
OutRequestId, *OculusXRColocation::ToString(ueResult));
return ueResult;
}
EColocationResult FOculusXRColocationFunctionsOVR::StopColocationDiscovery(uint64& OutRequestId)
{
ovrpResult result = FOculusXRHMDModule::GetPluginWrapper().StopColocationDiscovery(&OutRequestId);
auto ueResult = OculusXRColocation::GetResult(result);
UE_LOG(LogOculusXRColocation, Log, TEXT("[OVR::StopColocationDiscovery] RequestID: %llu, Launch async result: %s"),
OutRequestId, *OculusXRColocation::ToString(ueResult));
return ueResult;
}
EColocationResult FOculusXRColocationFunctionsOVR::StartColocationAdvertisement(const TArray<uint8>& MetaData, uint64& OutRequestId)
{
ovrpColocationAdvertisementStartInfo startInfo;
startInfo.Buffer = (ovrpByte*)MetaData.GetData();
startInfo.BufferSize = MetaData.Num();
ovrpResult result = FOculusXRHMDModule::GetPluginWrapper().StartColocationAdvertisement(&startInfo, &OutRequestId);
auto ueResult = OculusXRColocation::GetResult(result);
UE_LOG(LogOculusXRColocation, Log, TEXT("[OVR::StartColocationAdvertisement] RequestID: %llu, Launch async result: %s"),
OutRequestId, *OculusXRColocation::ToString(ueResult));
return ueResult;
}
EColocationResult FOculusXRColocationFunctionsOVR::StopColocationAdvertisement(uint64& OutRequestId)
{
ovrpResult result = FOculusXRHMDModule::GetPluginWrapper().StopColocationAdvertisement(&OutRequestId);
auto ueResult = OculusXRColocation::GetResult(result);
UE_LOG(LogOculusXRColocation, Log, TEXT("[OVR::StopColocationAdvertisement] RequestID: %llu, Launch async result: %s"),
OutRequestId, *OculusXRColocation::ToString(ueResult));
return ueResult;
}

View File

@@ -0,0 +1,15 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
#pragma once
#include "OculusXRColocationFunctions.h"
class OCULUSXRCOLOCATION_API FOculusXRColocationFunctionsOVR : public IOculusXRColocationFunctions
{
public:
virtual EColocationResult StartColocationDiscovery(uint64& OutRequestId) override;
virtual EColocationResult StopColocationDiscovery(uint64& OutRequestId) override;
virtual EColocationResult StartColocationAdvertisement(const TArray<uint8>& MetaData, uint64& OutRequestId) override;
virtual EColocationResult StopColocationAdvertisement(uint64& OutRequestId) override;
};

View File

@@ -0,0 +1,30 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
#include "OculusXRColocationFunctionsOpenXR.h"
#include "OculusXRHMD.h"
#include "OculusXRColocationUtil.h"
#include "OculusXRColocationModule.h"
EColocationResult FOculusXRColocationFunctionsOpenXR::StartColocationDiscovery(uint64& OutRequestId)
{
auto result = FOculusXRColocationModule::Get().GetXrColocation()->StartColocationDiscovery(OutRequestId);
return OculusXRColocation::GetResult(result);
}
EColocationResult FOculusXRColocationFunctionsOpenXR::StopColocationDiscovery(uint64& OutRequestId)
{
auto result = FOculusXRColocationModule::Get().GetXrColocation()->StopColocationDiscovery(OutRequestId);
return OculusXRColocation::GetResult(result);
}
EColocationResult FOculusXRColocationFunctionsOpenXR::StartColocationAdvertisement(const TArray<uint8>& MetaData, uint64& OutRequestId)
{
auto result = FOculusXRColocationModule::Get().GetXrColocation()->StartColocationAdvertisement(MetaData, OutRequestId);
return OculusXRColocation::GetResult(result);
}
EColocationResult FOculusXRColocationFunctionsOpenXR::StopColocationAdvertisement(uint64& OutRequestId)
{
auto result = FOculusXRColocationModule::Get().GetXrColocation()->StopColocationAdvertisement(OutRequestId);
return OculusXRColocation::GetResult(result);
}

View File

@@ -0,0 +1,16 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
#pragma once
#include <khronos/openxr/openxr.h>
#include "OculusXRColocationFunctions.h"
class OCULUSXRCOLOCATION_API FOculusXRColocationFunctionsOpenXR : public IOculusXRColocationFunctions
{
public:
virtual EColocationResult StartColocationDiscovery(uint64& OutRequestId) override;
virtual EColocationResult StopColocationDiscovery(uint64& OutRequestId) override;
virtual EColocationResult StartColocationAdvertisement(const TArray<uint8>& MetaData, uint64& OutRequestId) override;
virtual EColocationResult StopColocationAdvertisement(uint64& OutRequestId) override;
};

View File

@@ -0,0 +1,97 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
#include "OculusXRColocationLatentActions.h"
#include "OculusXRHMD.h"
#include "OculusXRAnchorBPFunctionLibrary.h"
#include "OculusXRColocationModule.h"
#include "OculusXRColocationSession.h"
#include "OculusXRAnchorManager.h"
//
// Find sessions
//
void UOculusXRAsyncAction_DiscoverColocationSessions::Activate()
{
OculusXRColocation::FColocation::DiscoverSessionsAsync(
OculusXRColocation::FDiscoverSessionsRequest::FCompleteDelegate::CreateUObject(this, &UOculusXRAsyncAction_DiscoverColocationSessions::HandleSessionFindComplete),
FOculusXRColocationSessionFoundDelegate::CreateUObject(this, &UOculusXRAsyncAction_DiscoverColocationSessions::HandleSessionFound));
}
UOculusXRAsyncAction_DiscoverColocationSessions* UOculusXRAsyncAction_DiscoverColocationSessions::OculusXRAsyncDiscoverColocationSessions()
{
UOculusXRAsyncAction_DiscoverColocationSessions* Action = NewObject<UOculusXRAsyncAction_DiscoverColocationSessions>();
Action->RegisterWithGameInstance(GWorld);
return Action;
}
void UOculusXRAsyncAction_DiscoverColocationSessions::HandleSessionFound(const FOculusXRColocationSession& Session)
{
TArray<FOculusXRColocationSession> emptyArray;
SessionFound.Broadcast(true, Session, emptyArray);
}
void UOculusXRAsyncAction_DiscoverColocationSessions::HandleSessionFindComplete(const OculusXRColocation::FDiscoverSessionsRequest::FResultType& Result)
{
if (Result.IsSuccess())
{
OnComplete.Broadcast(true, FOculusXRColocationSession(), Result.GetValue());
}
else
{
TArray<FOculusXRColocationSession> emptyArray;
OnComplete.Broadcast(false, FOculusXRColocationSession(), emptyArray);
}
SetReadyToDestroy();
}
//
// Start session advertisement
//
void UOculusXRAsyncAction_StartColocationSessionAdvertisement::Activate()
{
OculusXRColocation::FColocation::StartSessionAdvertisementAsync(
SessionData,
OculusXRColocation::FStartSessionAdvertisementRequest::FCompleteDelegate::CreateUObject(
this, &UOculusXRAsyncAction_StartColocationSessionAdvertisement::HandleStartSessionAdvertisementComplete));
}
UOculusXRAsyncAction_StartColocationSessionAdvertisement* UOculusXRAsyncAction_StartColocationSessionAdvertisement::OculusXRAsyncStartColocationSessionAdvertisement(const TArray<uint8>& SessionData)
{
UOculusXRAsyncAction_StartColocationSessionAdvertisement* Action = NewObject<UOculusXRAsyncAction_StartColocationSessionAdvertisement>();
Action->RegisterWithGameInstance(GWorld);
Action->SessionData = SessionData;
return Action;
}
void UOculusXRAsyncAction_StartColocationSessionAdvertisement::HandleStartSessionAdvertisementComplete(
const OculusXRColocation::FStartSessionAdvertisementRequest::FResultType& Result)
{
OnComplete.Broadcast(Result.IsSuccess(), Result.IsSuccess() ? Result.GetValue() : FOculusXRColocationSession());
SetReadyToDestroy();
}
//
// Stop session advertisement
//
void UOculusXRAsyncAction_StopColocationSessionAdvertisement::Activate()
{
OculusXRColocation::FColocation::StopSessionAdvertisementAsync(
OculusXRColocation::FStopSessionAdvertisementRequest::FCompleteDelegate::CreateUObject(
this, &UOculusXRAsyncAction_StopColocationSessionAdvertisement::HandleStopSessionAdvertisementComplete));
}
UOculusXRAsyncAction_StopColocationSessionAdvertisement* UOculusXRAsyncAction_StopColocationSessionAdvertisement::OculusXRAsyncStopColocationSessionAdvertisement()
{
UOculusXRAsyncAction_StopColocationSessionAdvertisement* Action = NewObject<UOculusXRAsyncAction_StopColocationSessionAdvertisement>();
Action->RegisterWithGameInstance(GWorld);
return Action;
}
void UOculusXRAsyncAction_StopColocationSessionAdvertisement::HandleStopSessionAdvertisementComplete(
const OculusXRColocation::FStopSessionAdvertisementRequest::FResultType& Result)
{
OnComplete.Broadcast(Result.IsSuccess());
SetReadyToDestroy();
}

View File

@@ -0,0 +1,57 @@
// @lint-ignore-every LICENSELINT
// Copyright Epic Games, Inc. All Rights Reserved.
#include "OculusXRColocationModule.h"
#include "IOculusXRHMDModule.h"
#if OCULUS_HMD_SUPPORTED_PLATFORMS
#include "OculusXRHMDModule.h"
#include "OculusXRHMD.h"
#include "OculusXRColocationEventPolling.h"
DEFINE_LOG_CATEGORY(LogOculusXRColocation);
#define LOCTEXT_NAMESPACE "OculusXRColocation"
//-------------------------------------------------------------------------------------------------
// FOculusXRColocationModule
//-------------------------------------------------------------------------------------------------
void FOculusXRColocationModule::StartupModule()
{
ColocationXR = MakeShareable(new XRColocation::FColocationXR());
ColocationXR->RegisterAsOpenXRExtension();
FCoreDelegates::OnPostEngineInit.AddRaw(this, &FOculusXRColocationModule::OnPostEngineInit);
}
void FOculusXRColocationModule::ShutdownModule()
{
}
void FOculusXRColocationModule::OnPostEngineInit()
{
if (IsRunningCommandlet())
{
return;
}
if (!GEngine)
{
return;
}
OculusXRHMD::FOculusXRHMD* HMD = OculusXRHMD::FOculusXRHMD::GetOculusXRHMD();
if (!HMD)
{
UE_LOG(LogOculusXRColocation, Warning, TEXT("Unable to retrieve OculusXRHMD, cannot add event polling delegate."));
return;
}
HMD->AddEventPollingDelegate(OculusXRHMD::FOculusXRHMDEventPollingDelegate::CreateStatic(&OculusXRColocation::FColocationEventPolling::OnPollEvent));
}
#endif // OCULUS_HMD_SUPPORTED_PLATFORMS
IMPLEMENT_MODULE(FOculusXRColocationModule, OculusXRColocation)
#undef LOCTEXT_NAMESPACE

View File

@@ -0,0 +1,52 @@
// @lint-ignore-every LICENSELINT
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "IOculusXRHMDModule.h"
#include "IOculusXRColocationModule.h"
#include "openxr/OculusXRColocationXR.h"
#define LOCTEXT_NAMESPACE "OculusColocation"
//-------------------------------------------------------------------------------------------------
// FOculusXRColocationModule
//-------------------------------------------------------------------------------------------------
#if OCULUS_HMD_SUPPORTED_PLATFORMS
DECLARE_LOG_CATEGORY_EXTERN(LogOculusXRColocation, Log, All);
typedef TSharedPtr<XRColocation::FColocationXR, ESPMode::ThreadSafe> FColocationXRPtr;
class FOculusXRColocationModule : public IOculusXRColocationModule
{
public:
static inline FOculusXRColocationModule& Get()
{
return FModuleManager::LoadModuleChecked<FOculusXRColocationModule>("OculusXRColocation");
}
virtual ~FOculusXRColocationModule() = default;
// IModuleInterface interface
virtual void StartupModule() override;
virtual void ShutdownModule() override;
FColocationXRPtr GetXrColocation() { return ColocationXR; }
private:
void OnPostEngineInit();
FColocationXRPtr ColocationXR;
};
#else // OCULUS_HMD_SUPPORTED_PLATFORMS
class FOculusXRColocationModule : public FDefaultModuleImpl
{
};
#endif // OCULUS_HMD_SUPPORTED_PLATFORMS
#undef LOCTEXT_NAMESPACE

View File

@@ -0,0 +1,195 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
#include "OculusXRColocationRequests.h"
#include "OculusXRColocationModule.h"
#include "OculusXRColocationUtil.h"
#include "OculusXRColocationSession.h"
#include "OculusXRColocationEventDelegates.h"
#include "OculusXRColocationSubsystem.h"
#include "OculusXRColocationFunctions.h"
#include "OculusXRHMDModule.h"
namespace OculusXRColocation
{
OculusXR::FAsyncRequestBase::RequestId DetermineRequestId(EColocationResult Result, uint64 Id)
{
return IsResultSuccess(Result) ? OculusXR::FAsyncRequestBase::RequestId(Id) : OculusXR::FAsyncRequestBase::RequestId(OculusXR::INVALID_TASK_REQUEST_ID);
}
FDiscoverSessionsRequest::FDiscoverSessionsRequest()
{
OnStartCompleteHandle = FOculusXRColocationEventDelegates::StartColocationDiscoveryComplete.AddStatic(
&FDiscoverSessionsRequest::OnStartComplete);
OnSessionFoundHandle = FOculusXRColocationEventDelegates::ColocationDiscoveryResultAvailable.AddStatic(
&FDiscoverSessionsRequest::OnResultAvailable);
OnStopCompleteHandle = FOculusXRColocationEventDelegates::StopColocationDiscoveryComplete.AddStatic(
&FDiscoverSessionsRequest::OnDiscoveryComplete);
OnDiscoveryCompleteHandle = FOculusXRColocationEventDelegates::StopColocationDiscoveryComplete.AddStatic(
&FDiscoverSessionsRequest::OnDiscoveryComplete);
}
FDiscoverSessionsRequest::~FDiscoverSessionsRequest()
{
}
void FDiscoverSessionsRequest::BindOnSessionFound(const FOculusXRColocationSessionFoundDelegate& OnSessionFound)
{
OnFoundSessionCallback = OnSessionFound;
}
void FDiscoverSessionsRequest::OnSessionFound(FOculusXRColocationSession&& Session)
{
auto index = FoundSessions.Emplace(Session);
OnFoundSessionCallback.ExecuteIfBound(FoundSessions[index]);
}
void FDiscoverSessionsRequest::OnInitRequest()
{
uint64 requestId;
auto result = IOculusXRColocationFunctions::GetOculusXRColocationFunctionsImpl()->StartColocationDiscovery(requestId);
UE_LOG(LogOculusXRColocation, Log, TEXT("Starting colocation session discovery. RequestID: %llu, Launch async result: %d"), requestId, result);
SetRequestId(DetermineRequestId(result, requestId));
SetInitialResult(result);
}
void FDiscoverSessionsRequest::OnStartComplete(FOculusXRUInt64 RequestId, EColocationResult Result)
{
auto taskPtr = OculusXR::FAsyncRequestSystem::GetRequest<FDiscoverSessionsRequest>(
OculusXR::FAsyncRequestBase::RequestId{ RequestId.GetValue() });
if (!taskPtr.IsValid())
{
return;
}
// If result succeeded we don't have complete the task but we do update the subsystem
if (IsResultSuccess(Result))
{
UOculusXRColocationSubsystem::Get()->SetDiscoveryRequest(taskPtr);
return;
}
OculusXR::FAsyncRequestSystem::CompleteRequest<FDiscoverSessionsRequest>(
taskPtr->GetEventId(),
FDiscoverSessionsRequest::FResultType::FromError(Result));
}
void FDiscoverSessionsRequest::OnResultAvailable(FOculusXRUInt64 RequestId, FOculusXRUUID Uuid, const TArray<uint8>& Metadata)
{
auto taskPtr = OculusXR::FAsyncRequestSystem::GetRequest<FDiscoverSessionsRequest>(
OculusXR::FAsyncRequestBase::RequestId{ RequestId.GetValue() });
if (!taskPtr.IsValid())
{
return;
}
FOculusXRColocationSession session;
session.Uuid = Uuid;
session.Metadata = Metadata;
taskPtr->OnSessionFound(std::move(session));
}
void FDiscoverSessionsRequest::OnDiscoveryComplete(FOculusXRUInt64 RequestId, EColocationResult Result)
{
auto taskPtr = OculusXR::FAsyncRequestSystem::GetRequest<FDiscoverSessionsRequest>(
OculusXR::FAsyncRequestBase::RequestId{ RequestId.GetValue() });
if (!taskPtr.IsValid())
{
return;
}
UOculusXRColocationSubsystem::Get()->ClearDiscoveryRequest();
OculusXR::FAsyncRequestSystem::CompleteRequest<FDiscoverSessionsRequest>(
taskPtr->GetEventId(),
FDiscoverSessionsRequest::FResultType::FromResult(Result, taskPtr->GetFoundSessions()));
}
FStartSessionAdvertisementRequest::FStartSessionAdvertisementRequest(const TArray<uint8>& SessionData)
: Data(SessionData)
{
OnStartCompleteHandle = FOculusXRColocationEventDelegates::StartColocationAdvertisementComplete.AddStatic(
&FStartSessionAdvertisementRequest::OnStartComplete);
}
FStartSessionAdvertisementRequest::~FStartSessionAdvertisementRequest()
{
FOculusXRColocationEventDelegates::StartColocationAdvertisementComplete.Remove(OnStartCompleteHandle);
}
void FStartSessionAdvertisementRequest::OnInitRequest()
{
uint64 requestId;
auto result = IOculusXRColocationFunctions::GetOculusXRColocationFunctionsImpl()->StartColocationAdvertisement(Data, requestId);
SetRequestId(DetermineRequestId(result, requestId));
SetInitialResult(result);
}
void FStartSessionAdvertisementRequest::OnStartComplete(FOculusXRUInt64 RequestId, FOculusXRUUID Uuid, EColocationResult Result)
{
auto taskPtr = OculusXR::FAsyncRequestSystem::GetRequest<FStartSessionAdvertisementRequest>(
OculusXR::FAsyncRequestBase::RequestId{ RequestId.GetValue() });
if (!taskPtr.IsValid())
{
return;
}
FOculusXRColocationSession session;
session.Uuid = Uuid;
session.Metadata = taskPtr->Data;
OculusXR::FAsyncRequestSystem::CompleteRequest<FStartSessionAdvertisementRequest>(
taskPtr->GetEventId(),
FStartSessionAdvertisementRequest::FResultType::FromResult(
Result,
session));
}
FStopSessionAdvertisementRequest::FStopSessionAdvertisementRequest()
{
OnStopCompleteHandle = FOculusXRColocationEventDelegates::StopColocationAdvertisementComplete.AddStatic(
&FStopSessionAdvertisementRequest::OnStopComplete);
OnCompleteHandle = FOculusXRColocationEventDelegates::ColocationAdvertisementComplete.AddStatic(
&FStopSessionAdvertisementRequest::OnStopComplete);
}
FStopSessionAdvertisementRequest::~FStopSessionAdvertisementRequest()
{
FOculusXRColocationEventDelegates::StopColocationAdvertisementComplete.Remove(OnStopCompleteHandle);
FOculusXRColocationEventDelegates::StopColocationAdvertisementComplete.Remove(OnCompleteHandle);
}
void FStopSessionAdvertisementRequest::OnInitRequest()
{
uint64 requestId;
auto result = IOculusXRColocationFunctions::GetOculusXRColocationFunctionsImpl()->StopColocationAdvertisement(requestId);
SetRequestId(DetermineRequestId(result, requestId));
SetInitialResult(result);
}
void FStopSessionAdvertisementRequest::OnStopComplete(FOculusXRUInt64 RequestId, EColocationResult Result)
{
auto taskPtr = OculusXR::FAsyncRequestSystem::GetRequest<FStopSessionAdvertisementRequest>(
OculusXR::FAsyncRequestBase::RequestId{ RequestId.GetValue() });
if (!taskPtr.IsValid())
{
return;
}
OculusXR::FAsyncRequestSystem::CompleteRequest<FStopSessionAdvertisementRequest>(
taskPtr->GetEventId(),
FStartSessionAdvertisementRequest::FResultType::FromResult(Result, UOculusXRColocationSubsystem::Get()->GetLocalSession()));
}
} // namespace OculusXRColocation

View File

@@ -0,0 +1,107 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
#include "OculusXRColocationSubsystem.h"
#include "OculusXRColocationModule.h"
#include "OculusXRColocationEventDelegates.h"
#include "OculusXRColocationUtil.h"
#include "OculusXRColocationRequests.h"
#include <Engine/GameInstance.h>
#include "Engine/Engine.h"
UOculusXRColocationSubsystem::UOculusXRColocationSubsystem() {}
UOculusXRColocationSubsystem* UOculusXRColocationSubsystem::Get()
{
if (GWorld != nullptr)
{
#if WITH_EDITOR
if (GIsEditor)
{
for (const FWorldContext& Context : GEngine->GetWorldContexts())
{
if (Context.WorldType == EWorldType::PIE)
{
return Context.World()->GetGameInstance()->GetSubsystem<UOculusXRColocationSubsystem>();
}
}
}
#endif // WITH_EDITOR
return GWorld->GetGameInstance()->GetSubsystem<UOculusXRColocationSubsystem>();
}
return nullptr;
}
void UOculusXRColocationSubsystem::Initialize(FSubsystemCollectionBase& Collection)
{
OnAdvertisementStartHandle = FOculusXRColocationEventDelegates::StartColocationAdvertisementComplete.AddUObject(this, &UOculusXRColocationSubsystem::OnColocationAdvertisementStart);
OnAdvertisementStoppedHandle = FOculusXRColocationEventDelegates::ColocationAdvertisementComplete.AddUObject(this, &UOculusXRColocationSubsystem::OnColocationAdvertisementStopped);
}
void UOculusXRColocationSubsystem::Deinitialize()
{
FOculusXRColocationEventDelegates::StartColocationAdvertisementComplete.Remove(OnAdvertisementStartHandle);
FOculusXRColocationEventDelegates::StartColocationAdvertisementComplete.Remove(OnAdvertisementStoppedHandle);
}
void UOculusXRColocationSubsystem::AssignLocalColocationSessionData(const FOculusXRUUID& Uuid, const TArray<uint8>& Data)
{
check(!bHasLocalSession);
LocalSession.Uuid = Uuid;
LocalSession.Metadata = Data;
bHasLocalSession = true;
}
void UOculusXRColocationSubsystem::ClearLocalColocationSession()
{
bHasLocalSession = false;
LocalSession.Uuid = FOculusXRUUID();
LocalSession.Metadata.Empty();
}
bool UOculusXRColocationSubsystem::HasLocalColocationSession() const
{
return bHasLocalSession;
}
const FOculusXRColocationSession& UOculusXRColocationSubsystem::GetLocalSession() const
{
check(bHasLocalSession);
return LocalSession;
}
void UOculusXRColocationSubsystem::SetDiscoveryRequest(TSharedPtr<OculusXRColocation::FDiscoverSessionsRequest> Request)
{
check(!DiscoverSessionsRequest.IsValid());
DiscoverSessionsRequest = Request;
}
void UOculusXRColocationSubsystem::ClearDiscoveryRequest()
{
DiscoverSessionsRequest = nullptr;
}
TSharedPtr<OculusXRColocation::FDiscoverSessionsRequest> UOculusXRColocationSubsystem::GetDiscoveryRequest() const
{
return DiscoverSessionsRequest;
}
void UOculusXRColocationSubsystem::OnColocationAdvertisementStart(FOculusXRUInt64 RequestId, FOculusXRUUID Uuid, EColocationResult Result)
{
if (OculusXRColocation::IsResultSuccess(Result))
{
auto taskPtr = OculusXR::FAsyncRequestSystem::GetRequest<OculusXRColocation::FStartSessionAdvertisementRequest>(
OculusXR::FAsyncRequestBase::RequestId{ RequestId.GetValue() });
if (taskPtr.IsValid())
{
AssignLocalColocationSessionData(Uuid, taskPtr->GetData());
}
}
}
void UOculusXRColocationSubsystem::OnColocationAdvertisementStopped(FOculusXRUInt64 RequestId, EColocationResult Result)
{
ClearLocalColocationSession();
}

View File

@@ -0,0 +1,96 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
#include "OculusXRColocationUtil.h"
namespace OculusXRColocation
{
EColocationResult GetResult(ovrpResult OVRResult)
{
switch (OVRResult)
{
case ovrpSuccess:
return EColocationResult::Success;
case ovrpSuccess_ColocationDiscoveryAlreadyAdvertising:
return EColocationResult::Success_AlreadyAdvertising;
case ovrpSuccess_ColocationDiscoveryAlreadyDiscovering:
return EColocationResult::Success_AlreadyDiscovering;
case ovrpFailure:
return EColocationResult::Failure;
case ovrpFailure_InvalidParameter:
return EColocationResult::FailureInvalidParameter;
case ovrpFailure_DataIsInvalid:
return EColocationResult::FailureDataIsInvalid;
case ovrpFailure_SpacePermissionInsufficient:
return EColocationResult::InsufficientPermissions;
case ovrpFailure_SpaceCloudStorageDisabled:
return EColocationResult::CloudStorageDisabled;
case ovrpFailure_SpaceNetworkTimeout:
return EColocationResult::NetworkTimeout;
case ovrpFailure_SpaceNetworkRequestFailed:
return EColocationResult::NetworkRequestFailed;
case ovrpFailure_ColocationDiscoveryNetworkFailed:
return EColocationResult::NetworkRequestFailed;
case ovrpFailure_ColocationDiscoveryNoDiscoveryMethodAvailable:
return EColocationResult::NoDiscoveryMethodAvailable;
default:
return OVRP_SUCCESS(OVRResult) ? EColocationResult::Success : EColocationResult::Failure;
}
}
EColocationResult GetResult(XrResult XRResult)
{
switch (XRResult)
{
case XR_SUCCESS:
return EColocationResult::Success;
case XR_COLOCATION_DISCOVERY_ALREADY_ADVERTISING_META:
return EColocationResult::Success_AlreadyAdvertising;
case XR_COLOCATION_DISCOVERY_ALREADY_DISCOVERING_META:
return EColocationResult::Success_AlreadyDiscovering;
case XR_ERROR_RUNTIME_FAILURE:
return EColocationResult::Failure;
case XR_ERROR_VALIDATION_FAILURE:
return EColocationResult::FailureInvalidParameter;
case XR_ERROR_SPACE_PERMISSION_INSUFFICIENT_META:
return EColocationResult::InsufficientPermissions;
case XR_ERROR_SPACE_CLOUD_STORAGE_DISABLED_FB:
return EColocationResult::CloudStorageDisabled;
case XR_ERROR_SPACE_NETWORK_TIMEOUT_FB:
return EColocationResult::NetworkTimeout;
case XR_ERROR_SPACE_NETWORK_REQUEST_FAILED_FB:
return EColocationResult::NetworkRequestFailed;
case XR_ERROR_COLOCATION_DISCOVERY_NETWORK_FAILED_META:
return EColocationResult::NetworkRequestFailed;
case XR_ERROR_COLOCATION_DISCOVERY_NO_DISCOVERY_METHOD_META:
return EColocationResult::NoDiscoveryMethodAvailable;
default:
return XR_SUCCEEDED(XRResult) ? EColocationResult::Success : EColocationResult::Failure;
}
}
const FString& ToString(EColocationResult Result)
{
// We could use UEnum::GetDisplayValueAsText but that will allocate!
const static TMap<EColocationResult, FString> Mapping = {
{ EColocationResult::Success, "Success" },
{ EColocationResult::Success_AlreadyAdvertising, "Success_AlreadyAdvertising" },
{ EColocationResult::Success_AlreadyDiscovering, "Success_AlreadyDiscovering" },
{ EColocationResult::Failure, "Failure" },
{ EColocationResult::FailureDataIsInvalid, "FailureDataIsInvalid" },
{ EColocationResult::FailureInvalidParameter, "FailureInvalidParameter" },
{ EColocationResult::InsufficientPermissions, "InsufficientPermissions" },
{ EColocationResult::CloudStorageDisabled, "CloudStorageDisabled" },
{ EColocationResult::NetworkRequestFailed, "NetworkRequestFailed" },
{ EColocationResult::NetworkTimeout, "NetworkTimeout" },
{ EColocationResult::NoDiscoveryMethodAvailable, "NoDiscoveryMethodAvailable" }
};
const static FString Invalid = "EColocationResult(Unknown)";
return Mapping.Contains(Result) ? Mapping[Result] : Invalid;
}
bool IsResultSuccess(EColocationResult Result)
{
return Result == EColocationResult::Success || Result == EColocationResult::Success_AlreadyAdvertising || Result == EColocationResult::Success_AlreadyDiscovering;
}
} // namespace OculusXRColocation

View File

@@ -0,0 +1,18 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
#pragma once
#include "openxr/OculusXRColocationXRIncludes.h"
#include "OculusXRAnchorTypes.h"
#include "OculusXRColocationTypes.h"
#include "OculusXRHMDPrivate.h"
namespace OculusXRColocation
{
EColocationResult GetResult(ovrpResult OVRResult);
EColocationResult GetResult(XrResult XRResult);
const FString& ToString(EColocationResult Result);
bool IsResultSuccess(EColocationResult Result);
} // namespace OculusXRColocation

View File

@@ -0,0 +1,285 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
#include "OculusXRColocationXR.h"
#include "OpenXRCore.h"
#include "OpenXRHMD.h"
#include "IOpenXRHMDModule.h"
#include "OpenXR/OculusXROpenXRUtilities.h"
#include "OculusXRAnchorsModule.h"
#include "OculusXRHMDPrivate.h"
#include "OculusXRColocationUtil.h"
#include "OculusXRColocationEventDelegates.h"
#include "OculusXRColocationModule.h"
#define LOCTEXT_NAMESPACE "OculusXRColocation"
namespace XRColocation
{
PFN_xrStartColocationDiscoveryMETA xrStartColocationDiscoveryMETA = nullptr;
PFN_xrStopColocationDiscoveryMETA xrStopColocationDiscoveryMETA = nullptr;
PFN_xrStartColocationAdvertisementMETA xrStartColocationAdvertisementMETA = nullptr;
PFN_xrStopColocationAdvertisementMETA xrStopColocationAdvertisementMETA = nullptr;
FColocationXR::FColocationXR()
: bExtColocationDiscoveryEnabled(false)
, OpenXRHMD(nullptr)
{
}
FColocationXR::~FColocationXR()
{
}
void FColocationXR::RegisterAsOpenXRExtension()
{
#if defined(WITH_OCULUS_BRANCH)
// Feature not enabled on Marketplace build. Currently only for the meta fork
RegisterOpenXRExtensionModularFeature();
#endif
}
bool FColocationXR::GetRequiredExtensions(TArray<const ANSICHAR*>& OutExtensions)
{
OutExtensions.Add(XR_META_COLOCATION_DISCOVERY_EXTENSION_NAME);
return true;
}
bool FColocationXR::GetOptionalExtensions(TArray<const ANSICHAR*>& OutExtensions)
{
return true;
}
const void* FColocationXR::OnCreateInstance(class IOpenXRHMDModule* InModule, const void* InNext)
{
if (InModule != nullptr)
{
bExtColocationDiscoveryEnabled = InModule->IsExtensionEnabled(XR_META_COLOCATION_DISCOVERY_EXTENSION_NAME);
UE_LOG(LogOculusXRColocation, Log, TEXT("[Colocation] Extensions available"));
UE_LOG(LogOculusXRColocation, Log, TEXT(" Colocation Discovery: %hs"), bExtColocationDiscoveryEnabled ? "ENABLED" : "DISABLED");
}
return InNext;
}
const void* FColocationXR::OnCreateSession(XrInstance InInstance, XrSystemId InSystem, const void* InNext)
{
InitOpenXRFunctions(InInstance);
const FName SystemName(TEXT("OpenXR"));
const bool IsOpenXR = GEngine->XRSystem.IsValid() && (GEngine->XRSystem->GetSystemName() == SystemName);
if (IsOpenXR)
{
OpenXRHMD = (FOpenXRHMD*)GEngine->XRSystem.Get();
}
return InNext;
}
void FColocationXR::OnDestroySession(XrSession InSession)
{
OpenXRHMD = nullptr;
}
void FColocationXR::OnEvent(XrSession InSession, const XrEventDataBaseHeader* InHeader)
{
if (OpenXRHMD == nullptr)
{
UE_LOG(LogOculusXRColocation, Log, TEXT("[FColocationXR::OnEvent] Receieved event but no HMD was present."));
return;
}
if (InHeader->type == XR_TYPE_EVENT_DATA_START_COLOCATION_DISCOVERY_COMPLETE_META)
{
const XrEventDataStartColocationDiscoveryCompleteMETA* const event =
reinterpret_cast<const XrEventDataStartColocationDiscoveryCompleteMETA*>(InHeader);
UE_LOG(LogOculusXRColocation, Verbose, TEXT("[FColocationXR::OnEvent] XrEventDataStartColocationDiscoveryCompleteMETA"));
UE_LOG(LogOculusXRColocation, Verbose, TEXT(" RequestId: %llu"), event->discoveryRequestId);
UE_LOG(LogOculusXRColocation, Verbose, TEXT(" Result: %d"), event->result);
FOculusXRColocationEventDelegates::StartColocationDiscoveryComplete.Broadcast(event->discoveryRequestId, OculusXRColocation::GetResult(event->result));
}
else if (InHeader->type == XR_TYPE_EVENT_DATA_COLOCATION_DISCOVERY_RESULT_META)
{
const XrEventDataColocationDiscoveryResultMETA* const event =
reinterpret_cast<const XrEventDataColocationDiscoveryResultMETA*>(InHeader);
UE_LOG(LogOculusXRColocation, Verbose, TEXT("[FColocationXR::OnEvent] XrEventDataStartColocationDiscoveryCompleteMETA"));
UE_LOG(LogOculusXRColocation, Verbose, TEXT(" RequestId: %s"), *FOculusXRUUID(event->advertisementUuid.data).ToString());
TArray<uint8> metadata(event->buffer, event->bufferSize);
FOculusXRColocationEventDelegates::ColocationDiscoveryResultAvailable.Broadcast(event->discoveryRequestId, event->advertisementUuid.data, metadata);
}
else if (InHeader->type == XR_TYPE_EVENT_DATA_COLOCATION_DISCOVERY_COMPLETE_META)
{
const XrEventDataColocationDiscoveryCompleteMETA* const event =
reinterpret_cast<const XrEventDataColocationDiscoveryCompleteMETA*>(InHeader);
UE_LOG(LogOculusXRColocation, Verbose, TEXT("[FColocationXR::OnEvent] XrEventDataColocationDiscoveryCompleteMETA"));
UE_LOG(LogOculusXRColocation, Verbose, TEXT(" RequestId: %llu"), event->discoveryRequestId);
UE_LOG(LogOculusXRColocation, Verbose, TEXT(" Result: %d"), event->result);
FOculusXRColocationEventDelegates::ColocationDiscoveryComplete.Broadcast(event->discoveryRequestId, OculusXRColocation::GetResult(event->result));
}
else if (InHeader->type == XR_TYPE_EVENT_DATA_STOP_COLOCATION_DISCOVERY_COMPLETE_META)
{
const XrEventDataStopColocationDiscoveryCompleteMETA* const event =
reinterpret_cast<const XrEventDataStopColocationDiscoveryCompleteMETA*>(InHeader);
UE_LOG(LogOculusXRColocation, Verbose, TEXT("[FColocationXR::OnEvent] XrEventDataStopColocationDiscoveryCompleteMETA"));
UE_LOG(LogOculusXRColocation, Verbose, TEXT(" RequestId: %llu"), event->requestId);
UE_LOG(LogOculusXRColocation, Verbose, TEXT(" Result: %d"), event->result);
FOculusXRColocationEventDelegates::StopColocationDiscoveryComplete.Broadcast(event->requestId, OculusXRColocation::GetResult(event->result));
}
else if (InHeader->type == XR_TYPE_EVENT_DATA_START_COLOCATION_ADVERTISEMENT_COMPLETE_META)
{
const XrEventDataStartColocationAdvertisementCompleteMETA* const event =
reinterpret_cast<const XrEventDataStartColocationAdvertisementCompleteMETA*>(InHeader);
UE_LOG(LogOculusXRColocation, Verbose, TEXT("[FColocationXR::OnEvent] XrEventDataStartColocationAdvertisementCompleteMETA"));
UE_LOG(LogOculusXRColocation, Verbose, TEXT(" RequestId: %llu"), event->advertisementRequestId);
UE_LOG(LogOculusXRColocation, Verbose, TEXT(" RequestId: %s"), *FOculusXRUUID(event->advertisementUuid.data).ToString());
UE_LOG(LogOculusXRColocation, Verbose, TEXT(" Result: %d"), event->result);
FOculusXRColocationEventDelegates::StartColocationAdvertisementComplete.Broadcast(event->advertisementRequestId, event->advertisementUuid.data, OculusXRColocation::GetResult(event->result));
}
else if (InHeader->type == XR_TYPE_EVENT_DATA_COLOCATION_ADVERTISEMENT_COMPLETE_META)
{
const XrEventDataColocationAdvertisementCompleteMETA* const event =
reinterpret_cast<const XrEventDataColocationAdvertisementCompleteMETA*>(InHeader);
UE_LOG(LogOculusXRColocation, Verbose, TEXT("[FColocationXR::OnEvent] XrEventDataColocationAdvertisementCompleteMETA"));
UE_LOG(LogOculusXRColocation, Verbose, TEXT(" RequestId: %llu"), event->advertisementRequestId);
UE_LOG(LogOculusXRColocation, Verbose, TEXT(" Result: %d"), event->result);
FOculusXRColocationEventDelegates::StopColocationDiscoveryComplete.Broadcast(event->advertisementRequestId, OculusXRColocation::GetResult(event->result));
}
else if (InHeader->type == XR_TYPE_EVENT_DATA_STOP_COLOCATION_ADVERTISEMENT_COMPLETE_META)
{
const XrEventDataStopColocationAdvertisementCompleteMETA* const event =
reinterpret_cast<const XrEventDataStopColocationAdvertisementCompleteMETA*>(InHeader);
UE_LOG(LogOculusXRColocation, Verbose, TEXT("[FColocationXR::OnEvent] XrEventDataStopColocationAdvertisementCompleteMETA"));
UE_LOG(LogOculusXRColocation, Verbose, TEXT(" RequestId: %llu"), event->requestId);
UE_LOG(LogOculusXRColocation, Verbose, TEXT(" Result: %d"), event->result);
FOculusXRColocationEventDelegates::StopColocationDiscoveryComplete.Broadcast(event->requestId, OculusXRColocation::GetResult(event->result));
}
}
XrResult FColocationXR::StartColocationDiscovery(uint64& OutRequestId)
{
if (!OpenXRHMD || !OpenXRHMD->GetInstance() || !OpenXRHMD->GetSession())
{
UE_LOG(LogOculusXRColocation, Warning, TEXT("[StartColocationDiscovery] XR state is invalid."));
return XR_ERROR_VALIDATION_FAILURE;
}
if (!IsColocationDiscoveryEnabled())
{
UE_LOG(LogOculusXRColocation, Warning, TEXT("[StartColocationDiscovery] Colocation discovery extensions are unsupported."));
return XR_ERROR_VALIDATION_FAILURE;
}
XrColocationDiscoveryStartInfoMETA info{ XR_TYPE_COLOCATION_DISCOVERY_START_INFO_META, nullptr };
auto result = xrStartColocationDiscoveryMETA(OpenXRHMD->GetSession(), &info, (XrAsyncRequestIdFB*)&OutRequestId);
if (!XR_SUCCEEDED(result))
{
UE_LOG(LogOculusXRColocation, Warning, TEXT("[StartColocationDiscovery] Start colocation discovery failed. Result: %d"), result);
}
return result;
}
XrResult FColocationXR::StopColocationDiscovery(uint64& OutRequestId)
{
if (!OpenXRHMD || !OpenXRHMD->GetInstance() || !OpenXRHMD->GetSession())
{
UE_LOG(LogOculusXRColocation, Warning, TEXT("[StopColocationDiscovery] XR state is invalid."));
return XR_ERROR_VALIDATION_FAILURE;
}
if (!IsColocationDiscoveryEnabled())
{
UE_LOG(LogOculusXRColocation, Warning, TEXT("[StopColocationDiscovery] Colocation discovery extensions are unsupported."));
return XR_ERROR_VALIDATION_FAILURE;
}
XrColocationDiscoveryStopInfoMETA info{ XR_TYPE_COLOCATION_DISCOVERY_STOP_INFO_META, nullptr };
auto result = xrStopColocationDiscoveryMETA(OpenXRHMD->GetSession(), &info, (XrAsyncRequestIdFB*)&OutRequestId);
if (!XR_SUCCEEDED(result))
{
UE_LOG(LogOculusXRColocation, Warning, TEXT("[StopColocationDiscovery] Stop colocation discovery failed. Result: %d"), result);
}
return result;
}
XrResult FColocationXR::StartColocationAdvertisement(const TArray<uint8>& Metadata, uint64& OutRequestId)
{
if (!OpenXRHMD || !OpenXRHMD->GetInstance() || !OpenXRHMD->GetSession())
{
UE_LOG(LogOculusXRColocation, Warning, TEXT("[StartColocationAdvertisement] XR state is invalid."));
return XR_ERROR_VALIDATION_FAILURE;
}
if (!IsColocationDiscoveryEnabled())
{
UE_LOG(LogOculusXRColocation, Warning, TEXT("[StartColocationAdvertisement] Colocation discovery extensions are unsupported."));
return XR_ERROR_VALIDATION_FAILURE;
}
XrColocationAdvertisementStartInfoMETA info{ XR_TYPE_COLOCATION_ADVERTISEMENT_START_INFO_META, nullptr };
info.buffer = (uint8_t*)Metadata.GetData();
info.bufferSize = Metadata.Num();
auto result = xrStartColocationAdvertisementMETA(OpenXRHMD->GetSession(), &info, (XrAsyncRequestIdFB*)&OutRequestId);
if (!XR_SUCCEEDED(result))
{
UE_LOG(LogOculusXRColocation, Warning, TEXT("[StartColocationAdvertisement] Start colocation advertisement failed. Result: %d"), result);
}
return result;
}
XrResult FColocationXR::StopColocationAdvertisement(uint64& OutRequestId)
{
if (!OpenXRHMD || !OpenXRHMD->GetInstance() || !OpenXRHMD->GetSession())
{
UE_LOG(LogOculusXRColocation, Warning, TEXT("[StopColocationAdvertisement] XR state is invalid."));
return XR_ERROR_VALIDATION_FAILURE;
}
if (!IsColocationDiscoveryEnabled())
{
UE_LOG(LogOculusXRColocation, Warning, TEXT("[StopColocationAdvertisement] Colocation discovery extensions are unsupported."));
return XR_ERROR_VALIDATION_FAILURE;
}
XrColocationAdvertisementStopInfoMETA info{ XR_TYPE_COLOCATION_ADVERTISEMENT_STOP_INFO_META, nullptr };
auto result = xrStopColocationAdvertisementMETA(OpenXRHMD->GetSession(), &info, (XrAsyncRequestIdFB*)&OutRequestId);
if (!XR_SUCCEEDED(result))
{
UE_LOG(LogOculusXRColocation, Warning, TEXT("[StopColocationAdvertisement] Stop colocation advertisement failed. Result: %d"), result);
}
return result;
}
void FColocationXR::InitOpenXRFunctions(XrInstance InInstance)
{
// XR_META_colocation_discovery
if (IsColocationDiscoveryEnabled())
{
OculusXR::XRGetInstanceProcAddr(InInstance, "xrStartColocationDiscoveryMETA", &xrStartColocationDiscoveryMETA);
OculusXR::XRGetInstanceProcAddr(InInstance, "xrStopColocationDiscoveryMETA", &xrStopColocationDiscoveryMETA);
OculusXR::XRGetInstanceProcAddr(InInstance, "xrStartColocationAdvertisementMETA", &xrStartColocationAdvertisementMETA);
OculusXR::XRGetInstanceProcAddr(InInstance, "xrStopColocationAdvertisementMETA", &xrStopColocationAdvertisementMETA);
}
}
} // namespace XRColocation
#undef LOCTEXT_NAMESPACE

View File

@@ -0,0 +1,54 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
#pragma once
#include "OculusXRColocationXRIncludes.h"
#include "IOpenXRExtensionPlugin.h"
#include "OculusXRColocationTypes.h"
#define LOCTEXT_NAMESPACE "OculusXRColocation"
class FOpenXRHMD;
namespace XRColocation
{
extern PFN_xrStartColocationDiscoveryMETA xrStartColocationDiscoveryMETA;
extern PFN_xrStopColocationDiscoveryMETA xrStopColocationDiscoveryMETA;
extern PFN_xrStartColocationAdvertisementMETA xrStartColocationAdvertisementMETA;
extern PFN_xrStopColocationAdvertisementMETA xrStopColocationAdvertisementMETA;
class FColocationXR : 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:
FColocationXR();
virtual ~FColocationXR();
void RegisterAsOpenXRExtension();
bool IsColocationDiscoveryEnabled() const { return bExtColocationDiscoveryEnabled; }
XrResult StartColocationDiscovery(uint64& OutRequestId);
XrResult StopColocationDiscovery(uint64& OutRequestId);
XrResult StartColocationAdvertisement(const TArray<uint8>& Metadata, uint64& OutRequestId);
XrResult StopColocationAdvertisement(uint64& OutRequestId);
private:
void InitOpenXRFunctions(XrInstance InInstance);
bool bExtColocationDiscoveryEnabled;
FOpenXRHMD* OpenXRHMD;
};
} // namespace XRColocation
#undef LOCTEXT_NAMESPACE

View File

@@ -0,0 +1,7 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
#pragma once
#include <khronos/openxr/openxr.h>
#include <khronos/openxr/meta_openxr_preview/meta_colocation_discovery.h>
#include "openxr/OculusXRAnchorsXRIncludes.h"

View File

@@ -0,0 +1,35 @@
// @lint-ignore-every LICENSELINT
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "Modules/ModuleManager.h"
/**
* The public interface to this module. In most cases, this interface is only public to sibling modules
* within this plugin.
*/
class IOculusXRColocationModule : public IModuleInterface
{
public:
/**
* Singleton-like access to this module's interface. This is just for convenience!
* Beware of calling this during the shutdown phase, though. Your module might have been unloaded already.
*
* @return Returns singleton instance, loading the module on demand if needed
*/
static inline IOculusXRColocationModule& Get()
{
return FModuleManager::LoadModuleChecked<IOculusXRColocationModule>("OculusXRColocation");
}
/**
* Checks to see if this module is loaded and ready. It is only valid to call Get() if IsAvailable() returns true.
*
* @return True if the module is loaded and ready to use
*/
static inline bool IsAvailable()
{
return FModuleManager::Get().IsModuleLoaded("OculusXRColocation");
}
};

View File

@@ -0,0 +1,19 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
#pragma once
#include "CoreMinimal.h"
#include "OculusXRColocationTypes.h"
#include "OculusXRColocationRequests.h"
namespace OculusXRColocation
{
struct OCULUSXRCOLOCATION_API FColocation
{
static TSharedPtr<FDiscoverSessionsRequest> DiscoverSessionsAsync(const FDiscoverSessionsRequest::FCompleteDelegate& OnComplete, const FOculusXRColocationSessionFoundDelegate& OnSessionFound);
static EColocationResult StopDiscoverSessions(TSharedPtr<FDiscoverSessionsRequest> Request);
static TSharedPtr<FStartSessionAdvertisementRequest> StartSessionAdvertisementAsync(const TArray<uint8>& SessionData, const FStartSessionAdvertisementRequest::FCompleteDelegate& OnComplete);
static TSharedPtr<FStopSessionAdvertisementRequest> StopSessionAdvertisementAsync(const FStopSessionAdvertisementRequest::FCompleteDelegate& OnComplete);
};
} // namespace OculusXRColocation

View File

@@ -0,0 +1,16 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
#pragma once
#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "OculusXRColocationFunctionLibrary.generated.h"
UCLASS()
class OCULUSXRCOLOCATION_API UOculusXRColocationFunctionLibrary : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
UFUNCTION(BlueprintCallable, Category = "OculusXR|Colocation")
static void StopColocationSessionDiscovery();
};

View File

@@ -0,0 +1,80 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
#pragma once
#include "Kismet/BlueprintAsyncActionBase.h"
#include "OculusXRColocationTypes.h"
#include "OculusXRColocation.h"
#include "OculusXRColocationSession.h"
#include "OculusXRColocationLatentActions.generated.h"
DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FOculusXR_LatentAction_ColocationDiscoveryComplete, bool, Success, const FOculusXRColocationSession&, Session, const TArray<FOculusXRColocationSession>&, FoundSessions);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FOculusXR_LatentAction_ColocationSessionFound, bool, Success, const FOculusXRColocationSession&, Session, const TArray<FOculusXRColocationSession>&, FoundSessions);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOculusXR_LatentAction_ColocationAdvertisementStarted, bool, Success, const FOculusXRColocationSession&, Session);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOculusXR_LatentAction_ColocationAdvertisementStopped, bool, Success);
//
// Find sessions
//
UCLASS()
class OCULUSXRCOLOCATION_API UOculusXRAsyncAction_DiscoverColocationSessions : public UBlueprintAsyncActionBase
{
GENERATED_BODY()
public:
virtual void Activate() override;
UFUNCTION(BlueprintCallable, meta = (BlueprintInternalUseOnly = "true"))
static UOculusXRAsyncAction_DiscoverColocationSessions* OculusXRAsyncDiscoverColocationSessions();
UPROPERTY(BlueprintAssignable)
FOculusXR_LatentAction_ColocationSessionFound SessionFound;
UPROPERTY(BlueprintAssignable)
FOculusXR_LatentAction_ColocationDiscoveryComplete OnComplete;
private:
void HandleSessionFound(const FOculusXRColocationSession& Session);
void HandleSessionFindComplete(const OculusXRColocation::FDiscoverSessionsRequest::FResultType& Result);
};
//
// Start advertisement
//
UCLASS()
class OCULUSXRCOLOCATION_API UOculusXRAsyncAction_StartColocationSessionAdvertisement : public UBlueprintAsyncActionBase
{
GENERATED_BODY()
public:
virtual void Activate() override;
UFUNCTION(BlueprintCallable, meta = (BlueprintInternalUseOnly = "true"))
static UOculusXRAsyncAction_StartColocationSessionAdvertisement* OculusXRAsyncStartColocationSessionAdvertisement(const TArray<uint8>& SessionData);
UPROPERTY(BlueprintAssignable)
FOculusXR_LatentAction_ColocationAdvertisementStarted OnComplete;
private:
TArray<uint8> SessionData;
void HandleStartSessionAdvertisementComplete(const OculusXRColocation::FStartSessionAdvertisementRequest::FResultType& Result);
};
//
// Stop advertisement
//
UCLASS()
class OCULUSXRCOLOCATION_API UOculusXRAsyncAction_StopColocationSessionAdvertisement : public UBlueprintAsyncActionBase
{
GENERATED_BODY()
public:
virtual void Activate() override;
UFUNCTION(BlueprintCallable, meta = (BlueprintInternalUseOnly = "true"))
static UOculusXRAsyncAction_StopColocationSessionAdvertisement* OculusXRAsyncStopColocationSessionAdvertisement();
UPROPERTY(BlueprintAssignable)
FOculusXR_LatentAction_ColocationAdvertisementStopped OnComplete;
private:
void HandleStopSessionAdvertisementComplete(const OculusXRColocation::FStopSessionAdvertisementRequest::FResultType& Result);
};

View File

@@ -0,0 +1,90 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
#pragma once
#include "OculusXRAsyncRequestSystem.h"
#include "OculusXRAsyncRequest.h"
#include "OculusXRColocationSession.h"
#include "OculusXRColocationTypes.h"
#include "OculusXRColocationUtil.h"
DECLARE_DELEGATE_OneParam(FOculusXRColocationSessionFoundDelegate, const FOculusXRColocationSession&);
namespace OculusXRColocation
{
struct FAsyncResultColocationDiscoverySuccess
{
bool operator()(EColocationResult Val) { return OculusXRColocation::IsResultSuccess(Val); }
};
template <typename TDerived, typename TValueType>
using FAsyncColocationRequest = OculusXR::FAsyncRequest<TDerived, EColocationResult, TValueType, FAsyncResultColocationDiscoverySuccess>;
// Discover nearby sessions
struct OCULUSXRCOLOCATION_API FDiscoverSessionsRequest :
FAsyncColocationRequest<FDiscoverSessionsRequest, TArray<FOculusXRColocationSession>>
{
public:
FDiscoverSessionsRequest();
~FDiscoverSessionsRequest();
void BindOnSessionFound(const FOculusXRColocationSessionFoundDelegate& OnSessionFound);
void OnSessionFound(FOculusXRColocationSession&& Session);
const TArray<FOculusXRColocationSession>& GetFoundSessions() const { return FoundSessions; }
protected:
virtual void OnInitRequest() override;
private:
static void OnStartComplete(FOculusXRUInt64 RequestId, EColocationResult Result);
static void OnResultAvailable(FOculusXRUInt64 RequestId, FOculusXRUUID Uuid, const TArray<uint8>& Metadata);
static void OnDiscoveryComplete(FOculusXRUInt64 RequestId, EColocationResult Result);
FDelegateHandle OnStartCompleteHandle;
FDelegateHandle OnSessionFoundHandle;
FDelegateHandle OnStopCompleteHandle;
FDelegateHandle OnDiscoveryCompleteHandle;
FOculusXRColocationSessionFoundDelegate OnFoundSessionCallback;
TArray<FOculusXRColocationSession> FoundSessions;
};
// Start advertisement, creates a session internally
struct OCULUSXRCOLOCATION_API FStartSessionAdvertisementRequest :
FAsyncColocationRequest<FStartSessionAdvertisementRequest, FOculusXRColocationSession>
{
public:
FStartSessionAdvertisementRequest(const TArray<uint8>& SessionData);
~FStartSessionAdvertisementRequest();
const TArray<uint8>& GetData() const { return Data; }
protected:
virtual void OnInitRequest() override;
private:
static void OnStartComplete(FOculusXRUInt64 RequestId, FOculusXRUUID Uuid, EColocationResult Result);
FDelegateHandle OnStartCompleteHandle;
TArray<uint8> Data;
};
// Stop advertisement, stops advertising and destroys the internal session
struct OCULUSXRCOLOCATION_API FStopSessionAdvertisementRequest :
FAsyncColocationRequest<FStopSessionAdvertisementRequest, FOculusXRColocationSession>
{
public:
FStopSessionAdvertisementRequest();
~FStopSessionAdvertisementRequest();
protected:
virtual void OnInitRequest() override;
private:
static void OnStopComplete(FOculusXRUInt64 RequestId, EColocationResult Result);
FDelegateHandle OnStopCompleteHandle;
FDelegateHandle OnCompleteHandle;
};
} // namespace OculusXRColocation

View File

@@ -0,0 +1,18 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
#pragma once
#include "OculusXRColocationTypes.h"
#include "OculusXRColocationSession.generated.h"
USTRUCT(BlueprintType)
struct OCULUSXRCOLOCATION_API FOculusXRColocationSession
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadOnly, Category = "OculusXR|Colocation")
FOculusXRUUID Uuid;
UPROPERTY(BlueprintReadOnly, Category = "OculusXR|Colocation")
TArray<uint8> Metadata;
};

View File

@@ -0,0 +1,42 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
#pragma once
#include "OculusXRColocationSession.h"
#include "OculusXRColocationRequests.h"
#include <Engine/World.h>
#include <Subsystems/GameInstanceSubsystem.h>
#include "OculusXRColocationSubsystem.generated.h"
UCLASS()
class OCULUSXRCOLOCATION_API UOculusXRColocationSubsystem : public UGameInstanceSubsystem
{
GENERATED_BODY()
public:
static UOculusXRColocationSubsystem* Get();
UOculusXRColocationSubsystem();
virtual void Initialize(FSubsystemCollectionBase& Collection) override;
virtual void Deinitialize() override;
void AssignLocalColocationSessionData(const FOculusXRUUID& Uuid, const TArray<uint8>& Data);
void ClearLocalColocationSession();
bool HasLocalColocationSession() const;
const FOculusXRColocationSession& GetLocalSession() const;
void SetDiscoveryRequest(TSharedPtr<OculusXRColocation::FDiscoverSessionsRequest> Request);
void ClearDiscoveryRequest();
TSharedPtr<OculusXRColocation::FDiscoverSessionsRequest> GetDiscoveryRequest() const;
private:
void OnColocationAdvertisementStart(FOculusXRUInt64 RequestId, FOculusXRUUID Uuid, EColocationResult Result);
void OnColocationAdvertisementStopped(FOculusXRUInt64 RequestId, EColocationResult Result);
FDelegateHandle OnAdvertisementStartHandle;
FDelegateHandle OnAdvertisementStoppedHandle;
bool bHasLocalSession;
FOculusXRColocationSession LocalSession;
TSharedPtr<OculusXRColocation::FDiscoverSessionsRequest> DiscoverSessionsRequest;
};

View File

@@ -0,0 +1,22 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
#pragma once
#include "OculusXRAnchorTypes.h"
#include "OculusXRColocationTypes.generated.h"
UENUM(BlueprintType)
enum class EColocationResult : uint8
{
Success,
Success_AlreadyAdvertising,
Success_AlreadyDiscovering,
Failure,
FailureInvalidParameter,
FailureDataIsInvalid,
NetworkTimeout,
NetworkRequestFailed,
InsufficientPermissions,
CloudStorageDisabled,
NoDiscoveryMethodAvailable,
};