// Copyright (c) Meta Platforms, Inc. and affiliates. // @generated by `buck2 run //arvr/projects/mixedreality/libraries/mrutilitykit:build_and_deploy unreal` #pragma once #include #include #include #include "CoreTypes.h" #include "Math/UnrealMath.h" #include "Math/MathFwd.h" struct MRUKShared { static MRUKShared* GetInstance() { return Instance; } static void LoadMRUKSharedLibrary(); static void FreeMRUKSharedLibrary(); struct MrukSceneAnchor; struct MrukRoomAnchor; struct MrukUuid; enum MrukSceneModel { MRUK_SCENE_MODEL_V2_FALLBACK_V1, MRUK_SCENE_MODEL_V1, MRUK_SCENE_MODEL_V2, }; enum MrukLogLevel { MRUK_LOG_LEVEL_DEBUG, MRUK_LOG_LEVEL_INFO, MRUK_LOG_LEVEL_WARN, MRUK_LOG_LEVEL_ERROR, }; enum MrukResult { MRUK_SUCCESS, MRUK_ERROR_INVALID_ARGS, MRUK_ERROR_UNKNOWN, MRUK_ERROR_INTERNAL, MRUK_ERROR_DISCOVERY_ONGOING, MRUK_ERROR_INVALID_JSON, MRUK_ERROR_NO_ROOMS_FOUND, MRUK_ERROR_INSUFFICIENT_RESOURCES, MRUK_ERROR_STORAGE_AT_CAPACITY, MRUK_ERROR_INSUFFICIENT_VIEW, MRUK_ERROR_PERMISSION_INSUFFICIENT, MRUK_ERROR_RATE_LIMITED, MRUK_ERROR_TOO_DARK, MRUK_ERROR_TOO_BRIGHT, }; enum MrukSurfaceType { MRUK_SURFACE_TYPE_NONE, MRUK_SURFACE_TYPE_PLANE, MRUK_SURFACE_TYPE_VOLUME, MRUK_SURFACE_TYPE_MESH, MRUK_SURFACE_TYPE_ALL, }; typedef void (*LogPrinter)(MrukLogLevel logLevel, const char* message); typedef void (*MrukOnPreRoomAnchorAdded)(const MrukRoomAnchor* roomAnchor, void* userContext); typedef void (*MrukOnRoomAnchorAdded)(const MrukRoomAnchor* roomAnchor, void* userContext); typedef void (*MrukOnRoomAnchorUpdated)(const MrukRoomAnchor* roomAnchor, const MrukUuid* oldRoomAnchorUuid, void* userContext); typedef void (*MrukOnRoomAnchorRemoved)(const MrukRoomAnchor* roomAnchor, void* userContext); typedef void (*MrukOnSceneAnchorAdded)(const MrukSceneAnchor* sceneAnchor, void* userContext); typedef void (*MrukOnSceneAnchorUpdated)(const MrukSceneAnchor* sceneAnchor, void* userContext); typedef void (*MrukOnSceneAnchorRemoved)(const MrukSceneAnchor* sceneAnchor, void* userContext); typedef void (*MrukOnDiscoveryFinished)(MrukResult result, void* userContext); struct MrukQuatf { float x; float y; float z; float w; }; struct MrukPosef { FVector3f position; MrukQuatf rotation; }; struct MrukPolygon2f { const FVector2f* points; uint32_t numPoints; }; struct MrukMesh2f { FVector2f* vertices; uint32_t numVertices; uint32_t* indices; uint32_t numIndices; }; struct MrukMesh3f { FVector3f* vertices; uint32_t numVertices; uint32_t* indices; uint32_t numIndices; }; struct MrukUuid { uint64_t part1; uint64_t part2; }; struct MrukVolume { FVector3f min; FVector3f max; }; struct MrukPlane { float x; float y; float width; float height; }; struct MrukSceneAnchor { uint64_t space; MrukUuid uuid; MrukUuid roomUuid; MrukPosef pose; MrukVolume volume; MrukPlane plane; char** semanticLabels; FVector2f* planeBoundary; uint32_t* globalMeshIndices; FVector3f* globalMeshPositions; uint32_t semanticLabelsCount; uint32_t planeBoundaryCount; uint32_t globalMeshIndicesCount; uint32_t globalMeshPositionsCount; bool hasVolume; bool hasPlane; }; struct MrukRoomAnchor { uint64_t space; MrukUuid uuid; }; struct MrukEventListener { MrukOnPreRoomAnchorAdded onPreRoomAnchorAdded; MrukOnRoomAnchorAdded onRoomAnchorAdded; MrukOnRoomAnchorUpdated onRoomAnchorUpdated; MrukOnRoomAnchorRemoved onRoomAnchorRemoved; MrukOnSceneAnchorAdded onSceneAnchorAdded; MrukOnSceneAnchorUpdated onSceneAnchorUpdated; MrukOnSceneAnchorRemoved onSceneAnchorRemoved; MrukOnDiscoveryFinished onDiscoveryFinished; void* userContext; }; struct MrukHit { MrukUuid roomAnchorUuid; MrukUuid sceneAnchorUuid; float hitDistance; FVector3f hitPosition; FVector3f hitNormal; }; void (*SetLogPrinter)(LogPrinter printer); /** * Create the global anchor store with a external OpenXR instance and session. * This should only be called once on application startup. * Make sure to hook up the ContextOnOpenXrEvent() function as well. * If the context is not needed anymore it should be destroyed with ContextDestroy() to free * resources. */ MrukResult (*AnchorStoreCreate)(uint64_t xrInstance, uint64_t xrSession, void* xrInstanceProcAddrFunc, uint64_t baseSpace); MrukResult (*AnchorStoreCreateWithoutOpenXr)(); /** * Destroy the global anchor store * This should only be called once on application shutdown. */ void (*AnchorStoreDestroy)(); /** * If the base space changes after initialization, this function should be called to update the * base space. */ void (*AnchorStoreSetBaseSpace)(uint64_t baseSpace); /** * Start anchor discovery in the anchor store */ MrukResult (*AnchorStoreStartDiscovery)(bool shouldRemoveMissingRooms, MrukSceneModel sceneModel); /** * Load the scene from a json string */ MrukResult (*AnchorStoreLoadSceneFromJson)(const char* jsonString, bool shouldRemoveMissingRooms, MrukSceneModel sceneModel); /** * Save the scene to a json string. * @return The serialized JSON string. This string must be freed with FreeAnchorStoreJson after use! */ const char* (*AnchorStoreSaveSceneToJson)(); /** * Free the json string returned by AnchorStoreSaveSceneToJson. * @param[in] jsonString The JSON string to free. */ void (*AnchorStoreFreeJson)(const char* jsonString); /** * Clear and remove all rooms in the anchor store. */ void (*AnchorStoreClearRooms)(); /** * Clear and remove the room that matches the given uuid. */ void (*AnchorStoreClearRoom)(MrukUuid roomUuid); /** * Allows to forward OpenXR events from the engine into the shared library */ void (*AnchorStoreOnOpenXrEvent)(void* baseEventHeader); /** * Needs to be called every tick by the engine. */ void (*AnchorStoreTick)(uint64_t nextPredictedDisplayTime); void (*AnchorStoreRegisterEventListener)(MrukEventListener listener); /** * Cast a ray against all anchors in the room and return the first hit. */ bool (*AnchorStoreRaycastRoom)(MrukUuid roomUuid, FVector3f origin, FVector3f direction, float maxDistance, uint32_t surfaceType, MrukHit* outHit); /** * Cast a ray against all anchors in the room and return all hits along the ray. */ bool (*AnchorStoreRaycastRoomAll)(MrukUuid roomUuid, FVector3f origin, FVector3f direction, float maxDistance, uint32_t surfaceType, MrukHit* outHits, uint32_t* outHitsCount); bool (*AnchorStoreIsDiscoveryRunning)(); /** * Add two vectors together. This is implemented as a test to ensure the native shared * library is working correctly. * * @param[in] a The first vector. * @param[in] b The second vector. * @return The sum of the two vectors. */ FVector3f (*AddVectors)(FVector3f a, FVector3f b); /** * Triangulate a polygon with holes, any winding order works. The first polyline defines the main * polygon. Following polylines define holes. This function will allocate memory for the vertices * and indices. You *MUST* call FreeMesh() when you are done with it or you will leak memory. * * @param[in] polygons The polygon to triangulate. * @param[in] numPolygons The number of polygons in the array. * @return mesh The triangulated mesh. */ MrukMesh2f (*TriangulatePolygon)(const MrukPolygon2f* polygons, uint32_t numPolygons); /** * Free the memory allocated by TriangulatePolygon. * * @param[in] mesh The mesh to free. */ void (*FreeMesh)(MrukMesh2f* mesh); /** * Compute the mesh segmentation for a given set of vertices, indices and segmentation points. * You *MUST* call FreeMeshSegmentation() on the meshSegments array when you are done with it or you * will leak memory. * * @param[in] vertices The mesh vertices. * @param[in] numVertices The number of vertices in the mesh. * @param[in] indices The mesh indices. * @param[in] numIndices The number of indices in the mesh. * @param[in] segmentationPoints The points that should be used to calculate the segments. * @param[in] numSegmentationPoints The number of segmentation points. * @param[in] reservedMin The minimum bounding box for the reserved segment. * @param[in] reservedMax The maximum bounding box for the reserved segment. * @param[out] meshSegments The resulting segments. * @param[out] numSegments The number of segments in the resulting array. * @param[out] reservedSegment The segment that is inside the reserved bounding box. */ MrukResult (*ComputeMeshSegmentation)(const FVector3f* vertices, uint32_t numVertices, const uint32_t* indices, uint32_t numIndices, const FVector3f* segmentationPoints, uint32_t numSegmentationPoints, FVector3f reservedMin, FVector3f reservedMax, MrukMesh3f** meshSegments, uint32_t* numSegments, MrukMesh3f* reservedSegment); /** * Free the memory allocated by ComputeMeshSegmentation. * * @param[in] meshSegments The array of segments to free. * @param[in] numSegments The number of segments in the array. * @param[in] reservedSegment The reserved segment to free. */ void (*FreeMeshSegmentation)(const MrukMesh3f* meshSegments, uint32_t numSegments, MrukMesh3f* reservedSegment); private: void LoadNativeFunctions() { SetLogPrinter = reinterpret_cast(LoadFunction(TEXT("SetLogPrinter"))); AnchorStoreCreate = reinterpret_cast(LoadFunction(TEXT("AnchorStoreCreate"))); AnchorStoreCreateWithoutOpenXr = reinterpret_cast(LoadFunction(TEXT("AnchorStoreCreateWithoutOpenXr"))); AnchorStoreDestroy = reinterpret_cast(LoadFunction(TEXT("AnchorStoreDestroy"))); AnchorStoreSetBaseSpace = reinterpret_cast(LoadFunction(TEXT("AnchorStoreSetBaseSpace"))); AnchorStoreStartDiscovery = reinterpret_cast(LoadFunction(TEXT("AnchorStoreStartDiscovery"))); AnchorStoreLoadSceneFromJson = reinterpret_cast(LoadFunction(TEXT("AnchorStoreLoadSceneFromJson"))); AnchorStoreSaveSceneToJson = reinterpret_cast(LoadFunction(TEXT("AnchorStoreSaveSceneToJson"))); AnchorStoreFreeJson = reinterpret_cast(LoadFunction(TEXT("AnchorStoreFreeJson"))); AnchorStoreClearRooms = reinterpret_cast(LoadFunction(TEXT("AnchorStoreClearRooms"))); AnchorStoreClearRoom = reinterpret_cast(LoadFunction(TEXT("AnchorStoreClearRoom"))); AnchorStoreOnOpenXrEvent = reinterpret_cast(LoadFunction(TEXT("AnchorStoreOnOpenXrEvent"))); AnchorStoreTick = reinterpret_cast(LoadFunction(TEXT("AnchorStoreTick"))); AnchorStoreRegisterEventListener = reinterpret_cast(LoadFunction(TEXT("AnchorStoreRegisterEventListener"))); AnchorStoreRaycastRoom = reinterpret_cast(LoadFunction(TEXT("AnchorStoreRaycastRoom"))); AnchorStoreRaycastRoomAll = reinterpret_cast(LoadFunction(TEXT("AnchorStoreRaycastRoomAll"))); AnchorStoreIsDiscoveryRunning = reinterpret_cast(LoadFunction(TEXT("AnchorStoreIsDiscoveryRunning"))); AddVectors = reinterpret_cast(LoadFunction(TEXT("AddVectors"))); TriangulatePolygon = reinterpret_cast(LoadFunction(TEXT("TriangulatePolygon"))); FreeMesh = reinterpret_cast(LoadFunction(TEXT("FreeMesh"))); ComputeMeshSegmentation = reinterpret_cast(LoadFunction(TEXT("ComputeMeshSegmentation"))); FreeMeshSegmentation = reinterpret_cast(LoadFunction(TEXT("FreeMeshSegmentation"))); } void UnloadNativeFunctions() { SetLogPrinter = nullptr; AnchorStoreCreate = nullptr; AnchorStoreCreateWithoutOpenXr = nullptr; AnchorStoreDestroy = nullptr; AnchorStoreSetBaseSpace = nullptr; AnchorStoreStartDiscovery = nullptr; AnchorStoreLoadSceneFromJson = nullptr; AnchorStoreSaveSceneToJson = nullptr; AnchorStoreFreeJson = nullptr; AnchorStoreClearRooms = nullptr; AnchorStoreClearRoom = nullptr; AnchorStoreOnOpenXrEvent = nullptr; AnchorStoreTick = nullptr; AnchorStoreRegisterEventListener = nullptr; AnchorStoreRaycastRoom = nullptr; AnchorStoreRaycastRoomAll = nullptr; AnchorStoreIsDiscoveryRunning = nullptr; AddVectors = nullptr; TriangulatePolygon = nullptr; FreeMesh = nullptr; ComputeMeshSegmentation = nullptr; FreeMeshSegmentation = nullptr; } void* LoadFunction(const TCHAR* ProcName); static MRUKShared* Instance; void* MRUKSharedHandle; MRUKShared(void* handle); ~MRUKShared(); };