From dc718f20667c3f54ae57aacd6b342b35a12653ab Mon Sep 17 00:00:00 2001 From: test Date: Mon, 19 Jul 2021 12:02:15 -0700 Subject: [PATCH 1/6] expose xr context for ios --- Dependencies/napi/napi-jsi/CMakeLists.txt | 2 +- Dependencies/xr/CMakeLists.txt | 1 + .../xr/Source/ARKit/Include/IXrContextARKit.h | 10 +++ Dependencies/xr/Source/ARKit/XR.mm | 69 ++++++++++++------- 4 files changed, 58 insertions(+), 24 deletions(-) create mode 100644 Dependencies/xr/Source/ARKit/Include/IXrContextARKit.h diff --git a/Dependencies/napi/napi-jsi/CMakeLists.txt b/Dependencies/napi/napi-jsi/CMakeLists.txt index 2d36ae64e..11bea67e3 100644 --- a/Dependencies/napi/napi-jsi/CMakeLists.txt +++ b/Dependencies/napi/napi-jsi/CMakeLists.txt @@ -13,7 +13,7 @@ add_library(napi ${SOURCES}) target_include_directories(napi PUBLIC "include") -target_link_to_dependencies(napi +target_link_libraries(napi PUBLIC jsi) if(WIN32) diff --git a/Dependencies/xr/CMakeLists.txt b/Dependencies/xr/CMakeLists.txt index e7d376d43..64e22759f 100644 --- a/Dependencies/xr/CMakeLists.txt +++ b/Dependencies/xr/CMakeLists.txt @@ -11,6 +11,7 @@ if (ANDROID) "Source/ARCore/XR.cpp") elseif (IOS) set(SOURCES ${SOURCES} + "Source/ARKit/Include/IXrContextARKit.h" "Source/ARKit/XR.mm") else() # Avoid picking up system installed jsoncpp in favor of source distributed with openxr_loader project diff --git a/Dependencies/xr/Source/ARKit/Include/IXrContextARKit.h b/Dependencies/xr/Source/ARKit/Include/IXrContextARKit.h new file mode 100644 index 000000000..2ba8ff31e --- /dev/null +++ b/Dependencies/xr/Source/ARKit/Include/IXrContextARKit.h @@ -0,0 +1,10 @@ +#pragma once + +#include + +typedef struct IXrContextARKit +{ + virtual bool IsInitialized() const = 0; + virtual ARSession* XrSession() const = 0; + virtual ARFrame* XrFrame() const = 0; +} IXrContextARKit; \ No newline at end of file diff --git a/Dependencies/xr/Source/ARKit/XR.mm b/Dependencies/xr/Source/ARKit/XR.mm index 714b10efa..9b65e7031 100644 --- a/Dependencies/xr/Source/ARKit/XR.mm +++ b/Dependencies/xr/Source/ARKit/XR.mm @@ -10,6 +10,8 @@ #import #import +#import "Include/IXrContextARKit.h" + @interface SessionDelegate : NSObject @end @@ -508,12 +510,37 @@ fragment float4 fragmentShader(RasterizerData in [[stage_in]], } } + struct XrContextARKit : public IXrContextARKit { + bool Initialized{true}; + ARSession* Session{nullptr}; + ARFrame* Frame{nullptr}; + + bool IsInitialized() const override + { + return Initialized; + } + + ARSession* XrSession() const override + { + return Session; + } + + ARFrame* XrFrame() const override + { + return Frame; + } + + virtual ~XrContextARKit() = default; + }; + struct System::Impl { public: + std::shared_ptr XrContext{std::make_shared()}; + Impl(const std::string&) {} bool IsInitialized() const { - return true; + return XrContext->IsInitialized(); } bool TryInitialize() { @@ -529,7 +556,6 @@ bool TryInitialize() { std::vector Planes{}; std::vector Meshes{}; std::vector FeaturePointCloud{}; - ARFrame* currentFrame{}; float DepthNearZ{ DEFAULT_DEPTH_NEAR_Z }; float DepthFarZ{ DEFAULT_DEPTH_FAR_Z }; bool FeaturePointCloudEnabled{ false }; @@ -540,18 +566,18 @@ bool TryInitialize() { , metalDevice{ (__bridge id)graphicsContext } { // Create the ARSession enable plane detection, and disable lighting estimation. - session = [ARSession new]; + SystemImpl.XrContext->Session = [ARSession new]; auto configuration = [ARWorldTrackingConfiguration new]; configuration.planeDetection = ARPlaneDetectionHorizontal | ARPlaneDetectionVertical; configuration.lightEstimationEnabled = false; configuration.worldAlignment = ARWorldAlignmentGravity; sessionDelegate = [[SessionDelegate new]init:&ActiveFrameViews metalContext:metalDevice]; - session.delegate = sessionDelegate; + SystemImpl.XrContext->Session.delegate = sessionDelegate; UpdateXRView(); - [session runWithConfiguration:configuration]; + [SystemImpl.XrContext->Session runWithConfiguration:configuration]; id lib = CompileShader(metalDevice, shaderSource); id vertexFunction = [lib newFunctionWithName:@"vertexShader"]; @@ -589,7 +615,7 @@ bool TryInitialize() { Planes.clear(); CleanupAnchor(nil); - [session pause]; + [SystemImpl.XrContext->Session pause]; UpdateXRView(nil); } @@ -635,7 +661,7 @@ void UpdateXRView(MTKView* activeXRView) { CFRunLoopRef mainRunLoop = CFRunLoopGetMain(); const auto intervalInSeconds = 0.033; CFRunLoopTimerRef timer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent(), intervalInSeconds, 0, 0, ^(CFRunLoopTimerRef timer){ - if ([session currentFrame] != nil) { + if ([SystemImpl.XrContext->Session currentFrame] != nil) { CFRunLoopRemoveTimer(mainRunLoop, timer, kCFRunLoopCommonModes); CFRelease(timer); tcs.complete(); @@ -649,11 +675,11 @@ void UpdateXRView(MTKView* activeXRView) { shouldEndSession = sessionEnded; shouldRestartSession = false; - currentFrame = session.currentFrame; + SystemImpl.XrContext->Frame = SystemImpl.XrContext->Session.currentFrame; UpdateXRView(); - [sessionDelegate session:session didUpdateFrameInternal:currentFrame]; + [sessionDelegate session:SystemImpl.XrContext->Session didUpdateFrameInternal:SystemImpl.XrContext->Frame]; auto viewSize = [sessionDelegate viewSize]; viewportSize.x = viewSize.width; @@ -804,13 +830,13 @@ void DrawFrame() { [commandBuffer commit]; } - if (currentFrame != nil) { - currentFrame = nil; + if (SystemImpl.XrContext->Frame != nil) { + SystemImpl.XrContext->Frame = nil; } } void GetHitTestResults(std::vector& filteredResults, xr::Ray offsetRay, xr::HitTestTrackableType trackableTypes) const { - if (currentFrame != nil && currentFrame.camera != nil && [currentFrame.camera trackingState] == ARTrackingStateNormal) { + if (SystemImpl.XrContext->Frame != nil && SystemImpl.XrContext->Frame.camera != nil && [SystemImpl.XrContext->Frame.camera trackingState] == ARTrackingStateNormal) { if (@available(iOS 13.0, *)) { GetHitTestResultsForiOS13(filteredResults, offsetRay, trackableTypes); } else { @@ -830,7 +856,7 @@ void GetHitTestResults(std::vector& filteredResults, xr::Ray offsetRa // Create the anchor and add it to the ARKit session. auto anchor = [[ARAnchor alloc] initWithTransform:poseTransform]; - [session addAnchor:anchor]; + [SystemImpl.XrContext->Session addAnchor:anchor]; nativeAnchors.push_back(anchor); return { pose, (__bridge NativeAnchorPtr)anchor }; } @@ -938,7 +964,7 @@ void UpdateFeaturePointCloud() { return; } - ARPointCloud* pointCloud = currentFrame.rawFeaturePoints; + ARPointCloud* pointCloud = SystemImpl.XrContext->Frame.rawFeaturePoints; FeaturePointCloud.resize(pointCloud.count); for (NSUInteger i = 0; i < pointCloud.count; i++) { @@ -990,7 +1016,7 @@ void CleanupAnchor(ARAnchor* arAnchor) { auto anchorIter = nativeAnchors.begin(); while (anchorIter != nativeAnchors.end()) { if (arAnchor == nil || arAnchor == *anchorIter) { - [session removeAnchor:*anchorIter]; + [SystemImpl.XrContext->Session removeAnchor:*anchorIter]; anchorIter = nativeAnchors.erase(anchorIter); if (arAnchor != nil) { @@ -1014,11 +1040,10 @@ bool IsTracking() const { // From my testing even while obscuring the camera for a long duration the state still registers as ARTrackingStateLimited // rather than ARTrackingStateNotAvailable. For that reason the only state that should be considered to be trully tracking is // ARTrackingStateNormal. - return currentFrame.camera.trackingState == ARTrackingState::ARTrackingStateNormal; + return SystemImpl.XrContext->Frame.camera.trackingState == ARTrackingState::ARTrackingStateNormal; } private: - ARSession* session{}; std::function getXRView{}; MTKView* xrView{}; bool sessionEnded{ false }; @@ -1123,7 +1148,7 @@ void PerformRaycastQueryAgainstTarget(std::vector& filteredResults, A alignment:ARRaycastTargetAlignmentAny]; // Perform the actual raycast. - auto rayCastResults = [session raycast:raycastQuery]; + auto rayCastResults = [SystemImpl.XrContext->Session raycast:raycastQuery]; // Process the results and push them into the results list. for (ARRaycastResult* result in rayCastResults) { @@ -1153,7 +1178,7 @@ void GetHitTestResultsLegacy(std::vector& filteredResults, xr::HitTes } // Now perform the actual hit test and process the results - auto hitTestResults = [currentFrame hitTest:CGPointMake(.5, .5) types:(typeFilter)]; + auto hitTestResults = [sessionImpl.Frame hitTest:CGPointMake(.5, .5) types:(typeFilter)]; for (ARHitTestResult* result in hitTestResults) { filteredResults.push_back(transformToHitResult(result.worldTransform)); } @@ -1241,14 +1266,12 @@ void GetHitTestResultsLegacy(std::vector& filteredResults, xr::HitTes uintptr_t System::GetNativeXrContext() { - // TODO - return 0; + return reinterpret_cast(m_impl->XrContext.get()); } std::string System::GetNativeXrContextType() { - // TODO - return ""; + return "ARKit"; } arcana::task, std::exception_ptr> System::Session::CreateAsync(System& system, void* graphicsDevice, std::function windowProvider) { From 982ae98940e507dc54d546fe97ddbdec2d60cee9 Mon Sep 17 00:00:00 2001 From: test Date: Mon, 19 Jul 2021 13:06:20 -0700 Subject: [PATCH 2/6] fix merge --- Dependencies/xr/Source/ARKit/XR.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dependencies/xr/Source/ARKit/XR.mm b/Dependencies/xr/Source/ARKit/XR.mm index 9b65e7031..b52547e0f 100644 --- a/Dependencies/xr/Source/ARKit/XR.mm +++ b/Dependencies/xr/Source/ARKit/XR.mm @@ -1178,7 +1178,7 @@ void GetHitTestResultsLegacy(std::vector& filteredResults, xr::HitTes } // Now perform the actual hit test and process the results - auto hitTestResults = [sessionImpl.Frame hitTest:CGPointMake(.5, .5) types:(typeFilter)]; + auto hitTestResults = [SystemImpl.XrContext->Frame hitTest:CGPointMake(.5, .5) types:(typeFilter)]; for (ARHitTestResult* result in hitTestResults) { filteredResults.push_back(transformToHitResult(result.worldTransform)); } From 8f03f49303d99db9ccacb270fee6a1b0bef50a4c Mon Sep 17 00:00:00 2001 From: test Date: Tue, 20 Jul 2021 09:58:23 -0700 Subject: [PATCH 3/6] implement declaring an anchor --- Dependencies/xr/Source/ARKit/XR.mm | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/Dependencies/xr/Source/ARKit/XR.mm b/Dependencies/xr/Source/ARKit/XR.mm index b52547e0f..5dc19e440 100644 --- a/Dependencies/xr/Source/ARKit/XR.mm +++ b/Dependencies/xr/Source/ARKit/XR.mm @@ -861,6 +861,17 @@ void GetHitTestResults(std::vector& filteredResults, xr::Ray offsetRa return { pose, (__bridge NativeAnchorPtr)anchor }; } + /** + Declares an ARKit anchor that was created outside the BabylonNative xr system. + */ + xr::Anchor DeclareAnchor(NativeAnchorPtr anchor) + { + const auto arAnchor = (__bridge ARAnchor*)anchor; + nativeAnchors.push_back(arAnchor); + const auto pose{TransformToPose(arAnchor.transform)}; + return { pose, anchor }; + } + /** For a given anchor update the current pose, and determine if it is still valid. */ @@ -1222,8 +1233,8 @@ void GetHitTestResultsLegacy(std::vector& filteredResults, xr::HitTes return m_impl->sessionImpl.CreateAnchor(pose); } - Anchor System::Session::Frame::DeclareAnchor(NativeAnchorPtr /*anchor*/) const { - throw std::runtime_error("not implemented"); + Anchor System::Session::Frame::DeclareAnchor(NativeAnchorPtr anchor) const { + return m_impl->sessionImpl.DeclareAnchor(anchor); } void System::Session::Frame::UpdateAnchor(xr::Anchor& anchor) const { From 1e8ad0f2526de8c6f221f8914dd17b88533b89a5 Mon Sep 17 00:00:00 2001 From: test Date: Tue, 20 Jul 2021 10:27:44 -0700 Subject: [PATCH 4/6] fix spaces --- Dependencies/xr/Source/ARKit/XR.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dependencies/xr/Source/ARKit/XR.mm b/Dependencies/xr/Source/ARKit/XR.mm index 80eaab9ed..e6db27d23 100644 --- a/Dependencies/xr/Source/ARKit/XR.mm +++ b/Dependencies/xr/Source/ARKit/XR.mm @@ -1516,7 +1516,7 @@ void GetHitTestResultsLegacy(std::vector& filteredResults, xr::HitTes Anchor System::Session::Frame::CreateAnchor(Pose pose, NativeTrackablePtr) const { return m_impl->sessionImpl.CreateAnchor(pose); } - + Anchor System::Session::Frame::DeclareAnchor(NativeAnchorPtr anchor) const { return m_impl->sessionImpl.DeclareAnchor(anchor); } From 90b082b72b0a5e478bfe75bbe8803454d380b653 Mon Sep 17 00:00:00 2001 From: test Date: Tue, 20 Jul 2021 10:35:03 -0700 Subject: [PATCH 5/6] revert cmake change --- Dependencies/napi/napi-jsi/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dependencies/napi/napi-jsi/CMakeLists.txt b/Dependencies/napi/napi-jsi/CMakeLists.txt index 11bea67e3..2d36ae64e 100644 --- a/Dependencies/napi/napi-jsi/CMakeLists.txt +++ b/Dependencies/napi/napi-jsi/CMakeLists.txt @@ -13,7 +13,7 @@ add_library(napi ${SOURCES}) target_include_directories(napi PUBLIC "include") -target_link_libraries(napi +target_link_to_dependencies(napi PUBLIC jsi) if(WIN32) From 3c203998519b2ec3b546048680dc05dff510b58b Mon Sep 17 00:00:00 2001 From: test Date: Tue, 20 Jul 2021 12:16:10 -0700 Subject: [PATCH 6/6] switch to unique ptr --- Dependencies/xr/Source/ARKit/XR.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dependencies/xr/Source/ARKit/XR.mm b/Dependencies/xr/Source/ARKit/XR.mm index e6db27d23..c6d034393 100644 --- a/Dependencies/xr/Source/ARKit/XR.mm +++ b/Dependencies/xr/Source/ARKit/XR.mm @@ -649,7 +649,7 @@ bool IsInitialized() const override struct System::Impl { public: - std::shared_ptr XrContext{std::make_shared()}; + std::unique_ptr XrContext{std::make_unique()}; Impl(const std::string&) {}