286 lines
12 KiB
C++
286 lines
12 KiB
C++
// 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
|