October3d55/Matain/ViveOpenXR/Source/ViveOpenXRAnchor/Private/ViveOpenXRAnchorFunctionLib...

186 lines
5.9 KiB
C++

// ViveOpenXRAnchorFunctionLibrary.cpp
// Copyright (c) 2024 HTC Corporation. All Rights Reserved.
#include "ViveOpenXRAnchorFunctionLibrary.h"
#include "ViveOpenXRAnchorPersistence.h"
#include "ViveOpenXRAnchorAsyncTask.h"
#include "ViveOpenXRAnchorModule.h"
#include "HAL/FileManager.h"
#include "Misc/Paths.h"
#include "Misc/FileHelper.h"
#include <string>
#include <inttypes.h>
bool UViveOpenXRAnchorFunctionLibrary::IsAnchorSupported()
{
if (!FViveOpenXRAnchor::Instance()) return false;
return FViveOpenXRAnchor::Instance()->IsSupported();
}
bool UViveOpenXRAnchorFunctionLibrary::CreateSpatialAnchor(FVector position, FRotator rotation, FString name, int64& anchor)
{
auto mod = FViveOpenXRAnchor::Instance();
auto hmd = FViveOpenXRAnchor::HMD();
if (!mod || !hmd) return false;
float w2m = hmd->GetWorldToMetersScale();
FQuat rot = FQuat(rotation);
XrSpatialAnchorCreateInfoHTC createInfo = mod->MakeCreateInfo(position, rot, hmd->GetTrackingSpace(), name, w2m);
anchor = 0;
XrSpace space;
if (!mod->CreateSpatialAnchor(&createInfo, &space))
return false;
anchor = (int64)space;
return true;
}
bool UViveOpenXRAnchorFunctionLibrary::CreateSpatialAnchorT(FTransform transform, FString name, int64& anchor)
{
return CreateSpatialAnchor(transform.GetLocation(), transform.GetRotation().Rotator(), name, anchor);
}
void UViveOpenXRAnchorFunctionLibrary::DestroySpatialAnchor(int64 anchor)
{
auto mod = FViveOpenXRAnchor::Instance();
if (!mod) return;
mod->DestroySpace((XrSpace)anchor);
}
bool UViveOpenXRAnchorFunctionLibrary::LocateAnchor(int64 anchor, FTransform& transform)
{
auto mod = FViveOpenXRAnchor::Instance();
if (!mod) return false;
FVector translation;
FRotator rotation;
if (!mod->LocateAnchor((XrSpace)anchor, rotation, translation))
return false;
transform = FTransform(rotation, translation, FVector(1, 1, 1));
return true;
}
bool UViveOpenXRAnchorFunctionLibrary::GetSpatialAnchorName(int64 anchor, FString& name)
{
auto mod = FViveOpenXRAnchor::Instance();
if (!mod) return false;
XrSpatialAnchorNameHTC xrName{};
xrName.name[0] = 0;
if (!mod->GetSpatialAnchorName((XrSpace)anchor, &xrName)) return false;
// Make sure the name is null-terminated
xrName.name[XR_MAX_SPATIAL_ANCHOR_NAME_SIZE_HTC - 1] = 0;
name = FString(xrName.name);
return true;
}
bool UViveOpenXRAnchorFunctionLibrary::IsPersistedAnchorSupported()
{
auto mod = FViveOpenXRAnchor::Instance();
if (!mod) return false;
return mod->IsPersistenceSupported();
}
bool UViveOpenXRAnchorFunctionLibrary::AcquirePersistedAnchorCollection(UPersistedAnchorCollection*& collectionObj, UObject* outer)
{
collectionObj = nullptr;
auto mod = FViveOpenXRAnchor::Instance();
if (!mod) return false;
XrFutureEXT future = XR_NULL_HANDLE;
XrResult result = mod->AcquirePersistedAnchorCollectionAsync(&future);
if (XR_FAILED(result))
{
UE_LOG(ViveOXRAnchor, Error, TEXT("Failed to acquire persisted anchor collection async: ret=%d"), result);
return false;
}
if (!outer) outer = GetTransientPackage();
collectionObj = UPersistedAnchorCollection::StartAcquirePACTask(future, outer);
return true;
}
void UViveOpenXRAnchorFunctionLibrary::ReleasePersistedAnchorCollection(UPersistedAnchorCollection* collectionObj)
{
auto mod = FViveOpenXRAnchor::Instance();
if (!mod) return;
if (collectionObj == nullptr) return;
XrPersistedAnchorCollectionHTC collection = (XrPersistedAnchorCollectionHTC)collectionObj->GetCollection();
if (collection == XR_NULL_HANDLE)
{
XrFutureEXT future = (XrFutureEXT)collectionObj->GetFuture();
if (future != XR_NULL_HANDLE)
collectionObj->CancelFuture();
}
XrResult result = mod->ReleasePersistedAnchorCollection(collection);
if (XR_FAILED(result))
{
UE_LOG(ViveOXRAnchor, Error, TEXT("Failed to release persisted anchor collection: %p ret=%d"), collection, result);
}
collectionObj->SetReleased();
}
FString UViveOpenXRAnchorFunctionLibrary::GetExternalStorageDir()
{
FString path = IFileManager::Get().ConvertToAbsolutePathForExternalAppForRead(*FPaths::ProjectDir());
//UE_LOG(ViveOXRAnchor, Log, TEXT("ProjectDir=%s"), *path);
#if PLATFORM_ANDROID
if (true)
#else
if (false)
#endif
{
FString internalPath = FPaths::Combine(TEXT("Android/data"), FApp::GetProjectName());
//UE_LOG(ViveOXRAnchor, Log, TEXT("internalPath=%s"), *internalPath);
if (path.Contains(internalPath)) {
path = path.Replace(*internalPath, TEXT(""));
path = FPaths::Combine(path, FApp::GetProjectName());
//UE_LOG(ViveOXRAnchor, Log, TEXT("ExternalStorageDir=%s"), *path);
}
}
return path;
}
bool UViveOpenXRAnchorFunctionLibrary::GetFilesInFolder(const FString& dirPath, const FString& extName, TArray<FString>& filenames) {
IFileManager& FileManager = IFileManager::Get();
FileManager.FindFiles(filenames, *dirPath, *extName);
//for (int i = 0; i < filenames.Num(); i++)
// UE_LOG(ViveOXRAnchor, Log, TEXT("GetFilesInFolder[%d] %s"), i, *filenames[i]);
return true;
}
bool UViveOpenXRAnchorFunctionLibrary::DeleteAnchorDirectory(const FString& dirPath)
{
IFileManager& FileManager = IFileManager::Get();
return FileManager.DeleteDirectory(*dirPath);
}
bool UViveOpenXRAnchorFunctionLibrary::SaveData(const TArray<unsigned char>& data, const FString& filePathname) {
if (FFileHelper::SaveArrayToFile(data, *filePathname)) {
UE_LOG(ViveOXRAnchor, Log, TEXT("Data is saved to %s"), *filePathname);
return true;
}
else {
UE_LOG(ViveOXRAnchor, Log, TEXT("Unable to save data to %s"), *filePathname);
return false;
}
}
bool UViveOpenXRAnchorFunctionLibrary::LoadData(const FString& filePathname, TArray<unsigned char>& data) {
if (FFileHelper::LoadFileToArray(data, *filePathname)) {
UE_LOG(ViveOXRAnchor, Log, TEXT("Load data[%d] from %s "), data.Num(), *filePathname);
return true;
}
else {
UE_LOG(ViveOXRAnchor, Log, TEXT("Unable to load data from %s"), *filePathname);
return false;
}
}
FString UViveOpenXRAnchorFunctionLibrary::ToString_Anchor(int64 anchor) {
return FString::Printf(TEXT("%016" PRIX64), (uint64_t)anchor);
}