// Copyright HTC Corporation. All Rights Reserved. #pragma once #include "ARBlueprintLibrary.h" #include "CoreMinimal.h" #include "IOpenXRARModule.h" #include "IOpenXRARTrackedGeometryHolder.h" #include "IOpenXRHMDModule.h" #include "IOpenXRExtensionPlugin.h" #include "IXRTrackingSystem.h" #include "OpenXRCore.h" #include "TrackedMeshCollision.h" #include "ViveOpenXRSceneUnderstandingFunctionLibrary.h" class IOpenXRARTrackedMeshHolder; inline bool operator==(const XrUuidMSFT& Lh, const XrUuidMSFT& Rh) noexcept { return memcmp(&Rh, &Lh, sizeof(XrUuidMSFT)) == 0; } inline bool operator!=(const XrUuidMSFT& Lh, const XrUuidMSFT& Rh) noexcept { return !(Lh == Rh); } // Allows XrUuidMSFT to be used as a key in TMap inline uint32 GetTypeHash(const XrUuidMSFT& Uuid) { static_assert(sizeof(XrUuidMSFT) == sizeof(uint64) * 2, ""); const uint64* V = reinterpret_cast(Uuid.bytes); return HashCombine(GetTypeHash(V[0]), GetTypeHash(V[1])); } inline FGuid XrUuidMSFTToFGuid(const XrUuidMSFT& Uuid) { static_assert(sizeof(FGuid) == sizeof(XrUuidMSFT), ""); FGuid OutGuid; FMemory::Memcpy(&OutGuid, &Uuid, sizeof(FGuid)); return OutGuid; } namespace ViveOpenXR { constexpr bool IsPoseValid(XrSpaceLocationFlags LocationFlags) { constexpr XrSpaceLocationFlags PoseValidFlags = XR_SPACE_LOCATION_POSITION_VALID_BIT | XR_SPACE_LOCATION_ORIENTATION_VALID_BIT; return (LocationFlags & PoseValidFlags) == PoseValidFlags; } enum class EXrSceneBoundType { XR_SCENE_BOUND_SPHERE_TYPE = 1, XR_SCENE_BOUND_ORIENTED_BOX_TYPE = 2, XR_SCENE_BOUND_FRUSTUM_TYPE = 3, XR_SCENE_BOUND_MAX = 4 }; enum class EMeshesScanState { Idle, Waiting, Updating, AddMeshesToTrackedMeshes, Locating }; struct FXrSpaceExtesionDispatchTable { PFN_xrEnumerateReferenceSpaces xrEnumerateReferenceSpaces; PFN_xrCreateReferenceSpace xrCreateReferenceSpace; PFN_xrDestroySpace xrDestroySpace; }; struct FSceneUnderstandingExtesionDispatchTable { PFN_xrEnumerateSceneComputeFeaturesMSFT xrEnumerateSceneComputeFeaturesMSFT; PFN_xrCreateSceneObserverMSFT xrCreateSceneObserverMSFT; PFN_xrDestroySceneObserverMSFT xrDestroySceneObserverMSFT; PFN_xrCreateSceneMSFT xrCreateSceneMSFT; PFN_xrDestroySceneMSFT xrDestroySceneMSFT; PFN_xrComputeNewSceneMSFT xrComputeNewSceneMSFT; PFN_xrGetSceneComputeStateMSFT xrGetSceneComputeStateMSFT; PFN_xrGetSceneComponentsMSFT xrGetSceneComponentsMSFT; PFN_xrLocateSceneComponentsMSFT xrLocateSceneComponentsMSFT; PFN_xrGetSceneMeshBuffersMSFT xrGetSceneMeshBuffersMSFT; }; struct FMeshInfo { XrUuidMSFT meshId; FGuid meshGuid; bool updated; }; struct FMeshUpdate { FGuid meshGuid; TArray vertices; TArray indices; }; class SharedOpenXRScene { public: /** * @param[in] scene A valid scene, which is created by xrCreateSceneMSFT. */ SharedOpenXRScene(FSceneUnderstandingExtesionDispatchTable SU_ext, XrSceneMSFT scene); ~SharedOpenXRScene(); XrSceneMSFT GetScene() const { return m_Scene; }; FSceneUnderstandingExtesionDispatchTable SU_ext{}; private: XrSceneObserverMSFT m_sceneObserver; XrSceneMSFT m_Scene; }; struct FMeshDataUpdate { TSharedPtr m_SharedOpenXRScene; TMap meshes; TMap meshCollisionInfo; }; class FSceneUnderstanding : public IOpenXRExtensionPlugin, public IOpenXRCustomCaptureSupport { public: FSceneUnderstanding(); ~FSceneUnderstanding(); XrSceneObserverMSFT m_SceneObserver = XR_NULL_HANDLE; void Register(); void Unregister(); /** IOpenXRExtensionPlugin implementation */ virtual const void* OnCreateSession(XrInstance InInstance, XrSystemId InSystem, const void* InNext) override; virtual const void* OnBeginSession(XrSession InSession, const void* InNext) override; virtual bool GetRequiredExtensions(TArray& OutExtensions) override; virtual void UpdateDeviceLocations(XrSession InSession, XrTime DisplayTime, XrSpace TrackingSpace) override; virtual bool OnToggleARCapture(const bool bOnOff) override; virtual void PostGetSystem(XrInstance InInstance, XrSystemId InSystem) override; virtual void OnDestroySession(XrSession InSession) override; virtual IOpenXRCustomCaptureSupport* GetCustomCaptureSupport(const EARCaptureType CaptureType) override; virtual TArray OnLineTraceTrackedObjects( const TSharedPtr ARCompositionComponent, const FVector Start, const FVector End, const EARLineTraceChannels TraceChannels) override; /** * Set a scene compute sphere bound. * Existing sphere bound will be replaced. */ void SetSceneComputeSphereBound(XrVector3f center, float radius); /** * Set a scene compute oriented box bound. * Existing oriented box bound will be replaced. */ void SetSceneComputeOrientedBoxBound(XrQuaternionf orientation, XrVector3f position, XrVector3f extents); /** * Set a scene compute oriented box bound. * Existing frustum bound will be replaced. */ void SetSceneComputeFrustumBound(XrQuaternionf orientation, XrVector3f position, float angleUp, float angleDown, float angleRight, float angleLeft, float farDistance); /** * Clear scene compute bounds of a specified type. */ void ClearSceneComputeBounds(EXrSceneBoundType type); void SetSceneComputeConsistency(XrSceneComputeConsistencyMSFT consistency); void SetMeshComputeLod(XrMeshComputeLodMSFT lod); bool m_bEnableSceneUnderstanding = false; private: void ComputeNewScene(XrTime displayTime); void LocateObjects(XrSceneMSFT scene, XrSpace BaseSpace, XrTime Time, const TArray& Identifiers, TArray& Locations); void ProcessMeshDataUpdate(FMeshDataUpdate&& meshDataUpdate, XrTime displayTime, XrSpace trackingSpace); void UpdateMeshesLocations(XrTime time, XrSpace space); TArray FVectorDoubleToFVectorFloat(TArray input); void Stop(); bool m_bOpenXRReady = false; TSharedPtr m_SharedScene; TMap m_PreviousMeshes; TMap m_Meshes; TArray m_Locations; TMap m_MeshCollisionInfo; int m_LocateCurrentFrame = 0; int m_NumOfMeshToDrawPerFrame = 5; FXrSpaceExtesionDispatchTable Space_ext{}; FSceneUnderstandingExtesionDispatchTable SU_ext{}; XrSession m_Session = XR_NULL_HANDLE; XrSpace m_XrSpace = XR_NULL_HANDLE; EMeshesScanState m_ScanState{ EMeshesScanState::Idle }; TArray m_SceneComputeFeatures; // Bounds TArray m_SceneSphereBounds; TArray m_SceneOrientedBoxBounds; TArray m_SceneFrustumBounds; TFuture> m_ScanedMeshFuture; class IXRTrackingSystem* XRTrackingSystem = nullptr; IOpenXRARTrackedMeshHolder* m_TrackedMeshHolder = nullptr; XrReferenceSpaceType m_ReferenceSpaceType; XrSceneComputeConsistencyMSFT m_SceneComputeConsistency{ XrSceneComputeConsistencyMSFT::XR_SCENE_COMPUTE_CONSISTENCY_SNAPSHOT_INCOMPLETE_FAST_MSFT }; XrMeshComputeLodMSFT m_MeshComputeLod{ XrMeshComputeLodMSFT::XR_MESH_COMPUTE_LOD_MEDIUM_MSFT }; }; }// namespace ViveOpenXR