// Copyright (c) Meta Platforms, Inc. and affiliates. #include "OculusXRSceneSubsystem.h" #include "OculusXRSceneTypes.h" #include "OculusXRScene.h" #include "IOculusXRSceneModule.h" #include "OculusXRSceneDelegates.h" #include "OculusXRAnchorBPFunctionLibrary.h" #include "OculusXRHMD.h" #include "OculusXRHMDRuntimeSettings.h" #include "OculusXRSceneModule.h" #include "OculusXRPassthroughModule.h" #include "OculusXRPassthroughXR.h" UOculusXRSceneSubsystem::UOculusXRSceneSubsystem() : requestedVisibilityState_(EOculusXRBoundaryVisibility::NotSuppressed) , bInitialized(false) { } bool UOculusXRSceneSubsystem::ShouldCreateSubsystem(UObject* Outer) const { return GetDefault()->bBoundaryVisibilitySupportEnabled && GetDefault()->bInsightPassthroughEnabled; } void UOculusXRSceneSubsystem::Initialize(FSubsystemCollectionBase& Collection) { bool enabled = GetDefault()->bBoundaryVisibilitySupportEnabled; bool suppressed = GetDefault()->bDefaultBoundaryVisibilitySuppressed; // This is the desired state bool isBoundaryNotSuppressed = enabled && !suppressed; requestedVisibilityState_ = isBoundaryNotSuppressed ? EOculusXRBoundaryVisibility::NotSuppressed : EOculusXRBoundaryVisibility::Suppressed; visChangedEventHandle_ = FOculusXRSceneEventDelegates::OculusBoundaryVisibilityChanged.AddUObject(this, &UOculusXRSceneSubsystem::OnBoundaryVisibilityChanged); bInitialized = true; } void UOculusXRSceneSubsystem::Deinitialize() { FOculusXRSceneEventDelegates::OculusBoundaryVisibilityChanged.Remove(visChangedEventHandle_); bInitialized = false; } ETickableTickType UOculusXRSceneSubsystem::GetTickableTickType() const { return IsTemplate() ? ETickableTickType::Never : FTickableGameObject::GetTickableTickType(); } bool UOculusXRSceneSubsystem::IsAllowedToTick() const { return !IsTemplate() && bInitialized; } void UOculusXRSceneSubsystem::Tick(float DeltaTime) { UpdateBoundary(); } EOculusXRBoundaryVisibility UOculusXRSceneSubsystem::GetBoundaryVisibility() { EOculusXRBoundaryVisibility boundaryVisibility = {}; OculusXRScene::FOculusXRScene::GetBoundaryVisibility(boundaryVisibility); return boundaryVisibility; } EOculusXRBoundaryVisibility UOculusXRSceneSubsystem::GetRequestedBoundaryVisibility() { return requestedVisibilityState_; } void UOculusXRSceneSubsystem::SetRequestedBoundaryVisibility(EOculusXRBoundaryVisibility Visibility) { requestedVisibilityState_ = Visibility; } void UOculusXRSceneSubsystem::OnBoundaryVisibilityChanged(EOculusXRBoundaryVisibility visibility) { // Do nothing on event } void UOculusXRSceneSubsystem::UpdateBoundary() { // If the state is the same, skip auto currentVisibilityState = GetBoundaryVisibility(); if (currentVisibilityState == requestedVisibilityState_) { return; } // Log only if the value != the requested state, else we pollute the log (per-frame call) UE_LOG(LogOculusXRScene, Log, TEXT("GetBoundaryVisibility -- Visibility(%s)"), *UEnum::GetValueAsString(currentVisibilityState)); // TODO: This should probably be part of the passthrough API const FName SystemName(TEXT("OpenXR")); const bool IsOpenXR = GEngine->XRSystem.IsValid() && (GEngine->XRSystem->GetSystemName() == SystemName); if (OculusXRHMD::FOculusXRHMD::GetOculusXRHMD() != nullptr) { // If passthrough is not enabled or initialized, skip auto result = FOculusXRHMDModule::GetPluginWrapper().GetInsightPassthroughInitializationState(); bool passthroughInitializedOrPending = (result >= 0); bool passthroughEnabled = GetDefault()->bInsightPassthroughEnabled; if (!passthroughEnabled || !passthroughInitializedOrPending) { return; } } else if (IsOpenXR) { if (!FOculusXRPassthroughModule::Get().GetPassthroughExtensionPlugin().Pin()->IsPassthroughEnabled()) { return; } } OculusXRScene::FOculusXRScene::RequestBoundaryVisibility(requestedVisibilityState_); }