Files
OpenVulkano/openVulkanoCpp/AR/Provider/ArKit/ArSessionArKitInternal.mm

138 lines
3.5 KiB
Plaintext

/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#include "ArSessionArKitInternal.h"
#include "ArFrameArKit.h"
#include "ArTrackingStateConverter.h"
#include "Base/Logger.hpp"
#include "IO/AppFolders.hpp"
#include <sstream>
#import <ARKit/ARSession.h>
#import <ARKit/ARFrame.h>
#import <ARKit/ARConfiguration.h>
#import <ARKit/ARCamera.h>
#import <ARKit/ARKit.h>
#import <CoreVideo/CoreVideo.h>
#import "ArKitDelegate.h"
#define VALIDATE_SESSION(s) if(s != m_arSession) { Logger::AR->warn("ARSession does not match."); return; }
namespace openVulkanoCpp::AR::ArKit
{
ArSessionArKitInternal::ArSessionArKitInternal(const ArSessionConfig& config)
: m_frameId(0)
{
m_arKitDelegate = [[ArKitDelegate alloc] initWithFrameHandler:this];
m_arConfig = [ARWorldTrackingConfiguration new];
if (config.enableDepth)
{
m_arConfig.frameSemantics = ARFrameSemanticSceneDepth;
}
m_arSession = [ARSession new];
m_arSession.delegate = m_arKitDelegate;
m_loopClosureDetectionAnchor = nil;
running = false;
}
ArSessionArKitInternal::~ArSessionArKitInternal()
{
Stop();
[m_arSession release];
[m_arConfig release];
[m_arKitDelegate release];
}
void ArSessionArKitInternal::Start()
{
[m_arSession runWithConfiguration:m_arConfig];
running = true;
}
void ArSessionArKitInternal::Stop()
{
[m_arSession pause];
#if (__cplusplus >= 202002L)
m_frame = nullptr;
#else
m_frame.Access()->reset();
#endif
running = false;
}
void ArSessionArKitInternal::Pause()
{
ArSession::Pause();
}
double timestamp = 0;
std::shared_ptr<ArFrame> ArSessionArKitInternal::GetFrame()
{
if (GetRecorder().GetRecordingMode() == RecordingMode::FRAME_REQUEST)
GetRecorder().Save(m_frame);
return m_frame;
}
void ArSessionArKitInternal::RequestHighResolutionFrame()
{
Logger::AR->error("Failed to perform high resolution still frame capture: not supported on this platform!");
}
// AR Kit delegate events
void ArSessionArKitInternal::OnArNewFrame(ARSession* session, ARFrame* frame)
{
VALIDATE_SESSION(session);
std::shared_ptr<ArFrame> arFrame = std::make_shared<ArFrameArKit>(frame, shared_from_this());
OnNewFrame(arFrame);
OnNewCameraTransformation(arFrame->GetCameraTransformation());
if (OnNewCameraViewMatrix.HasHandlers())
{
auto view = arFrame->GetCameraViewForCurrentDeviceOrientation();
OnNewCameraViewMatrix(view);
}
OnNewFrameAvailable();
m_frame = arFrame;
}
void ArSessionArKitInternal::OnArSessionInterruptedChanged(ARSession* session, bool interrupted)
{
VALIDATE_SESSION(session);
Logger::AR->info("Ar session {}", interrupted ? "interrupted" : "resumed");
OnSessionInterruptionChange.NotifyAll(interrupted);
}
void ArSessionArKitInternal::OnArSessionFailed(ARSession* session, NSError* error)
{
VALIDATE_SESSION(session);
Logger::AR->warn("AR Session failed, description: {}", [[error description] UTF8String]);
std::string failReason = [[error localizedDescription] UTF8String];
OnSessionFailed(failReason);
}
void ArSessionArKitInternal::OnArCameraTrackingChange(ARSession* session, ARCamera* camera)
{
VALIDATE_SESSION(session);
OnTrackingStateChanged(GetArTrackingState(camera));
}
void ArSessionArKitInternal::OnArAnchorsUpdate(NSArray<__kindof ARAnchor*>* anchors)
{
Logger::AR->info("Anchors updated.");
OnAnchorsUpdated();
}
bool ArSessionArKitInternal::ArShouldAttemptRelocalization()
{
return shouldAttemptRelocalization;
}
}