582 lines
16 KiB
C++
582 lines
16 KiB
C++
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
||
|
|
||
|
#include "OculusXRAnchorLatentActions.h"
|
||
|
#include "OculusXRAnchorsPrivate.h"
|
||
|
#include "OculusXRHMD.h"
|
||
|
#include "OculusXRAnchorBPFunctionLibrary.h"
|
||
|
#include "OculusXRRoomLayoutManager.h"
|
||
|
#include "OculusXRAnchorDelegates.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();
|
||
|
}
|
||
|
|
||
|
|
||
|
UOculusXRAnchorLaunchCaptureFlow* UOculusXRAnchorLaunchCaptureFlow::LaunchCaptureFlowAsync(const UObject* WorldContext)
|
||
|
{
|
||
|
UWorld* World = GEngine->GetWorldFromContextObject(WorldContext, EGetWorldErrorMode::ReturnNull);
|
||
|
if (!ensureAlwaysMsgf(IsValid(WorldContext), TEXT("World Context was not valid.")))
|
||
|
{
|
||
|
return nullptr;
|
||
|
}
|
||
|
|
||
|
// Create a new UMyDelayAsyncAction, and store function arguments in it.
|
||
|
auto NewAction = NewObject<UOculusXRAnchorLaunchCaptureFlow>();
|
||
|
NewAction->RegisterWithGameInstance(World->GetGameInstance());
|
||
|
return NewAction;
|
||
|
}
|
||
|
|
||
|
void UOculusXRAnchorLaunchCaptureFlow::Activate()
|
||
|
{
|
||
|
Request = 0;
|
||
|
FOculusXRAnchorEventDelegates::OculusSceneCaptureComplete.AddUObject(this, &UOculusXRAnchorLaunchCaptureFlow::OnCaptureFinish);
|
||
|
bool CaptureStarted = OculusXRAnchors::FOculusXRRoomLayoutManager::RequestSceneCapture(Request);
|
||
|
if (!CaptureStarted)
|
||
|
{
|
||
|
FOculusXRAnchorEventDelegates::OculusSceneCaptureComplete.RemoveAll(this);
|
||
|
Failure.Broadcast();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void UOculusXRAnchorLaunchCaptureFlow::OnCaptureFinish(FOculusXRUInt64 RequestId, bool bSuccess)
|
||
|
{
|
||
|
if (Request != RequestId.GetValue())
|
||
|
{
|
||
|
UE_LOG(LogOculusXRAnchors, Warning, TEXT("%llu request id doesn't match %llu. Ignoring request."), RequestId, Request);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
FOculusXRAnchorEventDelegates::OculusSceneCaptureComplete.RemoveAll(this);
|
||
|
Success.Broadcast();
|
||
|
SetReadyToDestroy();
|
||
|
}
|