2025-03-10 09:43:27 +08:00
// Copyright® 2015-2023 PICO Technology Co., Ltd. All rights reserved.
// This plugin incorporates portions of the Unreal® Engine. Unreal® is a trademark or registered trademark of Epic Games, Inc. in the United States of America and elsewhere.
// Unreal® Engine, Copyright 1998 – 2023, Epic Games, Inc. All rights reserved.
# include "PICO_MRFunctionLibrary.h"
# include "PICOOpenXRRuntimeSettings.h"
# include "PICO_SceneCapture.h"
# include "PICO_SpatialAnchor.h"
# include "PICO_SpatialMesh.h"
2025-07-21 10:22:56 +08:00
# include "ProceduralMeshComponent.h"
2025-03-10 09:43:27 +08:00
# include "Engine/Engine.h"
# include "Engine/World.h"
2025-07-21 10:22:56 +08:00
# include "Materials/Material.h"
# include "Materials/MaterialInterface.h"
2025-03-10 09:43:27 +08:00
UMRDelegateManagerPICO * UMRFunctionLibraryPICO : : PICODelegateManager = nullptr ;
UMRDelegateManagerPICO * UMRFunctionLibraryPICO : : GetMRDelegateManagerPICO ( )
{
if ( PICODelegateManager = = nullptr )
{
PICODelegateManager = NewObject < UMRDelegateManagerPICO > ( ) ;
PICODelegateManager - > AddToRoot ( ) ;
}
return PICODelegateManager ;
}
bool UMRFunctionLibraryPICO : : GetAnchorEntityUuidPICO ( AActor * BoundActor , FSpatialUUIDPICO & OutAnchorUUID , EResultPICO & OutResult )
{
if ( ! IsValid ( BoundActor ) | | ! IsValid ( BoundActor - > GetWorld ( ) ) )
{
return false ;
}
UAnchorComponentPICO * AnchorComponent = Cast < UAnchorComponentPICO > ( BoundActor - > GetComponentByClass ( UAnchorComponentPICO : : StaticClass ( ) ) ) ;
if ( IsValid ( AnchorComponent ) & & AnchorComponent - > IsAnchorValid ( ) )
{
return FSpatialAnchorExtensionPICO : : GetInstance ( ) - > GetAnchorEntityUUID ( AnchorComponent , OutAnchorUUID , OutResult ) ;
}
return false ;
}
bool UMRFunctionLibraryPICO : : GetAnchorEntityUuidByComponentPICO ( UAnchorComponentPICO * AnchorComponent , FSpatialUUIDPICO & OutAnchorUUID , EResultPICO & OutResult )
{
if ( IsValid ( AnchorComponent ) & & AnchorComponent - > IsAnchorValid ( ) )
{
return FSpatialAnchorExtensionPICO : : GetInstance ( ) - > GetAnchorEntityUUID ( AnchorComponent , OutAnchorUUID , OutResult ) ;
}
return false ;
}
bool UMRFunctionLibraryPICO : : GetSceneBoundingBox2DPICO ( const FSpatialUUIDPICO & UUID , FBoundingBox2DPICO & Box2D )
{
return FSceneCaptureExtensionPICO : : GetInstance ( ) - > GetSpatialSceneBoundingBox2D ( UUID , Box2D ) ;
}
bool UMRFunctionLibraryPICO : : GetSceneBoundingPolygonPICO ( const FSpatialUUIDPICO & UUID , TArray < FVector > & OutPolygonVertices )
{
return FSceneCaptureExtensionPICO : : GetInstance ( ) - > GetSpatialSceneBoundingPolygon ( UUID , OutPolygonVertices ) ;
}
bool UMRFunctionLibraryPICO : : GetSceneBoundingBox3DPICO ( const FSpatialUUIDPICO & UUID , FBoundingBox3DPICO & Box3D )
{
return FSceneCaptureExtensionPICO : : GetInstance ( ) - > GetSpatialSceneBoundingBox3D ( UUID , Box3D ) ;
}
bool UMRFunctionLibraryPICO : : GetAnchorPoseByActorPICO ( AActor * BoundActor , FTransform & OutTransform , EResultPICO & OutResult )
{
if ( ! IsValid ( BoundActor ) | | ! IsValid ( BoundActor - > GetWorld ( ) ) )
{
return false ;
}
UAnchorComponentPICO * AnchorComponent = Cast < UAnchorComponentPICO > ( BoundActor - > GetComponentByClass ( UAnchorComponentPICO : : StaticClass ( ) ) ) ;
if ( IsValid ( AnchorComponent ) & & AnchorComponent - > IsAnchorValid ( ) )
{
return FSpatialAnchorExtensionPICO : : GetInstance ( ) - > GetAnchorPose ( AnchorComponent , OutTransform , OutResult ) ;
}
return false ;
}
bool UMRFunctionLibraryPICO : : GetAnchorPoseByComponentPICO ( UAnchorComponentPICO * AnchorComponent , FTransform & OutTransform , EResultPICO & OutResult )
{
if ( IsValid ( AnchorComponent ) & & AnchorComponent - > IsAnchorValid ( ) )
{
return FSpatialAnchorExtensionPICO : : GetInstance ( ) - > GetAnchorPose ( AnchorComponent , OutTransform , OutResult ) ;
}
return false ;
}
AActor * UMRFunctionLibraryPICO : : SpawnActorFromLoadResultPICO ( UObject * WorldContext , const FAnchorLoadResultPICO & LoadResult , UClass * ActorClass )
{
UWorld * World = GEngine - > GetWorldFromContextObject ( WorldContext , EGetWorldErrorMode : : ReturnNull ) ;
if ( ! IsValid ( World ) )
{
return nullptr ;
}
FActorSpawnParameters SpawnInfo ;
SpawnInfo . ObjectFlags | = RF_Transient ;
AActor * AnchorActor = World - > SpawnActor ( ActorClass , nullptr , nullptr , SpawnInfo ) ;
if ( ! IsValid ( AnchorActor ) )
{
return nullptr ;
}
UAnchorComponentPICO * AnchorComponent = Cast < UAnchorComponentPICO > ( AnchorActor - > GetComponentByClass ( UAnchorComponentPICO : : StaticClass ( ) ) ) ;
if ( IsValid ( AnchorComponent ) & & AnchorComponent - > IsAnchorValid ( ) )
{
return AnchorActor ;
}
if ( AnchorComponent = = nullptr )
{
AnchorComponent = Cast < UAnchorComponentPICO > ( AnchorActor - > AddComponentByClass ( UAnchorComponentPICO : : StaticClass ( ) , false , FTransform : : Identity , false ) ) ;
}
AnchorComponent - > SetAnchorHandle ( LoadResult . AnchorHandle ) ;
return AnchorActor ;
}
bool UMRFunctionLibraryPICO : : IsAnchorValidForActorPICO ( AActor * BoundActor )
{
if ( ! IsValid ( BoundActor ) )
{
return false ;
}
UAnchorComponentPICO * AnchorComponent = Cast < UAnchorComponentPICO > ( BoundActor - > GetComponentByClass ( UAnchorComponentPICO : : StaticClass ( ) ) ) ;
if ( IsValid ( AnchorComponent ) & & AnchorComponent - > IsAnchorValid ( ) )
{
return true ;
}
return false ;
}
bool UMRFunctionLibraryPICO : : IsAnchorValidForComponentPICO ( UAnchorComponentPICO * AnchorComponent )
{
if ( IsValid ( AnchorComponent ) & & AnchorComponent - > IsAnchorValid ( ) )
{
return true ;
}
return false ;
}
FString UMRFunctionLibraryPICO : : FromAnchorToStringPICO ( const FSpatialHandlePICO & Anchor )
{
return Anchor . ToString ( ) ;
}
FString UMRFunctionLibraryPICO : : FromUUIDToStringPICO ( const FSpatialUUIDPICO & AnchorUUID )
{
return AnchorUUID . ToString ( ) ;
}
FSpatialUUIDPICO UMRFunctionLibraryPICO : : FromStringToUUIDPICO ( const FString & AnchorUUIDString )
{
FSpatialUUIDPICO OutAnchorUUID = { } ;
// Static size for the max length of the string, two chars per hex digit, 16 digits.
checkf ( AnchorUUIDString . Len ( ) = = 32 , TEXT ( " '%s' is not a valid UUID " ) , * AnchorUUIDString ) ;
HexToBytes ( AnchorUUIDString , OutAnchorUUID . UUIDArray ) ;
return OutAnchorUUID ;
}
bool UMRFunctionLibraryPICO : : CloseSpatialMeshScanningPICO ( EResultPICO & OutResult )
{
return FSpatialMeshExtensionPICO : : GetInstance ( ) - > StopProvider ( OutResult ) ;
}
bool UMRFunctionLibraryPICO : : ChangeSpatialMeshLodSettingPICO ( ESpatialMeshLodPICO SpatialMeshLod , EResultPICO & OutResult )
{
bool bResult = false ;
if ( FSpatialMeshExtensionPICO : : GetInstance ( ) - > GetCurrentSpatialMeshLod ( ) ! = SpatialMeshLod )
{
bResult = FSpatialMeshExtensionPICO : : GetInstance ( ) - > StopProvider ( OutResult ) ;
if ( bResult )
{
bResult = FSpatialMeshExtensionPICO : : GetInstance ( ) - > DestroyProvider ( OutResult ) ;
if ( bResult )
{
FSenseDataProviderCreateInfoMeshPICO cFPICOSenseDataProviderCreateInfoMesh = { } ;
cFPICOSenseDataProviderCreateInfoMesh . Lod = SpatialMeshLod ;
const UPICOOpenXRRuntimeSettings * Settings = GetDefault < UPICOOpenXRRuntimeSettings > ( ) ;
if ( Settings )
{
if ( Settings - > bSemanticsAlignWithTriangle )
{
cFPICOSenseDataProviderCreateInfoMesh . ConfigArray . Add ( ESpatialMeshConfigPICO : : Spatial_Mesh_Config_Semantic ) ;
}
else if ( Settings - > bSemanticsAlignWithVertex )
{
cFPICOSenseDataProviderCreateInfoMesh . ConfigArray . Add ( ESpatialMeshConfigPICO : : Spatial_Mesh_Config_Semantic ) ;
cFPICOSenseDataProviderCreateInfoMesh . ConfigArray . Add ( ESpatialMeshConfigPICO : : Spatial_Mesh_Config_Semantic_Align_With_Vertex ) ;
}
}
bResult = FSpatialMeshExtensionPICO : : GetInstance ( ) - > CreateProvider ( cFPICOSenseDataProviderCreateInfoMesh , OutResult ) ;
}
}
}
return bResult ;
}
ESpatialMeshLodPICO UMRFunctionLibraryPICO : : GetSpatialMeshLodSettingPICO ( )
{
return FSpatialMeshExtensionPICO : : GetInstance ( ) - > GetCurrentSpatialMeshLod ( ) ;
}
EMRStatePICO UMRFunctionLibraryPICO : : GetSpatialMeshScanningStatePICO ( )
{
return FSpatialMeshExtensionPICO : : GetInstance ( ) - > GetSenseDataProviderState ( ) ;
}
EMRStatePICO UMRFunctionLibraryPICO : : GetSpatialAnchorServiceStatePICO ( )
{
return FSpatialAnchorExtensionPICO : : GetInstance ( ) - > GetSenseDataProviderState ( ) ;
}
EMRStatePICO UMRFunctionLibraryPICO : : GetSceneCaptureServiceStatePICO ( )
{
return FSceneCaptureExtensionPICO : : GetInstance ( ) - > GetSenseDataProviderState ( ) ;
}
void UMRFunctionLibraryPICO : : ResetSpatialMeshInfosStatePICO ( )
{
FSpatialMeshExtensionPICO : : GetInstance ( ) - > ClearMeshProviderBuffer ( ) ;
}
bool UMRFunctionLibraryPICO : : CloseSpatialAnchorServicePICO ( EResultPICO & OutResult )
{
return FSpatialAnchorExtensionPICO : : GetInstance ( ) - > StopProvider ( OutResult ) ;
}
bool UMRFunctionLibraryPICO : : CloseSceneCaptureServicePICO ( EResultPICO & OutResult )
{
return FSceneCaptureExtensionPICO : : GetInstance ( ) - > StopProvider ( OutResult ) ;
}
bool UMRFunctionLibraryPICO : : DestroyAnchorByComponentPICO ( UAnchorComponentPICO * AnchorComponent , EResultPICO & OutResult )
{
bool bResult = false ;
if ( IsValid ( AnchorComponent ) & & AnchorComponent - > IsAnchorValid ( ) )
{
bResult = FSpatialAnchorExtensionPICO : : GetInstance ( ) - > DestroyAnchorByHandle ( AnchorComponent - > GetAnchorHandle ( ) , OutResult ) ;
AnchorComponent - > ResetAnchorHandle ( ) ;
}
return bResult ;
}
bool UMRFunctionLibraryPICO : : DestroyAnchorByActorPICO ( AActor * BoundActor , EResultPICO & OutResult )
{
bool bResult = false ;
if ( ! IsValid ( BoundActor ) | | ! IsValid ( BoundActor - > GetWorld ( ) ) )
{
return bResult ;
}
UAnchorComponentPICO * AnchorComponent = Cast < UAnchorComponentPICO > ( BoundActor - > GetComponentByClass ( UAnchorComponentPICO : : StaticClass ( ) ) ) ;
if ( IsValid ( AnchorComponent ) & & AnchorComponent - > IsAnchorValid ( ) )
{
bResult = FSpatialAnchorExtensionPICO : : GetInstance ( ) - > DestroyAnchorByHandle ( AnchorComponent - > GetAnchorHandle ( ) , OutResult ) ;
AnchorComponent - > ResetAnchorHandle ( ) ;
}
return bResult ;
}
bool UMRFunctionLibraryPICO : : CreateSceneBoundingPolygonPICO ( AActor * BoundActor , bool bNeverCreateCollision , bool bFlipPolygon , bool UseWireframe , const FTransform & Transform , const TArray < FVector > & BoundaryVertices , UMaterialInterface * DefaultMeshMaterial )
{
2025-07-21 10:22:56 +08:00
auto MRMeshComponent = NewObject < UProceduralMeshComponent > ( BoundActor ) ;
TArray < int32 > Indices ;
TArray < FVector > Normals ;
TArray < FLinearColor > VertexColors ;
TArray < FProcMeshTangent > Tangents ;
TArray < FVector2D > UV0 ;
2025-03-10 09:43:27 +08:00
if ( ! IsValid ( BoundActor ) | | ! BoundaryVertices . Num ( ) | | ! DefaultMeshMaterial )
{
return false ;
}
MRMeshComponent - > SetUsingAbsoluteLocation ( true ) ;
MRMeshComponent - > SetUsingAbsoluteRotation ( true ) ;
MRMeshComponent - > SetUsingAbsoluteScale ( true ) ;
2025-07-21 10:22:56 +08:00
if ( UseWireframe & & GEngine - > WireframeMaterial )
{
MRMeshComponent - > SetMaterial ( 0 , GEngine - > WireframeMaterial ) ;
}
else
2025-03-10 09:43:27 +08:00
{
MRMeshComponent - > SetMaterial ( 0 , DefaultMeshMaterial ) ;
}
MRMeshComponent - > SetupAttachment ( BoundActor - > GetRootComponent ( ) ) ;
MRMeshComponent - > RegisterComponent ( ) ;
auto Vertices = BoundaryVertices ;
const auto NumPolygons = Vertices . Num ( ) ;
Indices . Reset ( 3 * NumPolygons ) ;
if ( bFlipPolygon )
{
for ( auto Index = 0 ; Index < NumPolygons ; + + Index )
{
Indices . Add ( 0 ) ;
Indices . Add ( ( Index + 2 ) % NumPolygons ) ;
Indices . Add ( ( Index + 1 ) % NumPolygons ) ;
}
}
else
{
for ( auto Index = 0 ; Index < NumPolygons ; + + Index )
{
Indices . Add ( 0 ) ;
Indices . Add ( ( Index + 1 ) % NumPolygons ) ;
Indices . Add ( ( Index + 2 ) % NumPolygons ) ;
}
}
2025-07-21 10:22:56 +08:00
MRMeshComponent - > CreateMeshSection_LinearColor ( 0 , Vertices , Indices , Normals , UV0 , VertexColors , Tangents , ! bNeverCreateCollision ) ;
MRMeshComponent - > SetWorldLocation ( Transform . GetLocation ( ) ) ;
MRMeshComponent - > SetWorldRotation ( Transform . GetRotation ( ) ) ;
2025-03-10 09:43:27 +08:00
return true ;
}