138 lines
3.5 KiB
Plaintext
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;
|
|
}
|
|
}
|