Files
OpenVulkano/openVulkanoCpp/AR/ArSession.cpp
2021-06-21 16:12:31 +02:00

130 lines
3.8 KiB
C++

/*
* 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 "ArSession.hpp"
#include "Provider/Playback/ArSessionPlayback.h"
#include "Provider/Network/ArSessionStream.h"
#ifdef __APPLE__
#include "Provider/ArKit/ArSessionArKit.h"
#else
#ifdef ANDROID
#include "Provider/ArCore/ArSessionArCore.h"
#else
#include "Provider/ArSessionNull.hpp"
#endif
#endif
namespace openVulkanoCpp::AR
{
std::vector<std::weak_ptr<ArSession>> ArSession::sessions;
std::weak_ptr<ArSession> ArSession::nativeSession;
ArCreateResult ArSession::Create(const ArSessionConfig& config)
{
if (!IsNativeArAvailable())
{
return { nullptr, ArCreateResult::FAILED_NOT_SUPPORTED, "No native AR implementation available for current system." };
}
if (auto session = nativeSession.lock())
{
return { session, ArCreateResult::FAILED_ALREADY_CREATED, "Session has already been created. Return existing session." };
}
if (!GetNativeCapabilities().IsDepthSupported() && config.enableDepth)
{
return { nullptr, ArCreateResult::FAILED_INCOMPATIBLE_CONFIG, "AR depth is not supported on the current system." };
}
try
{
if (auto session = NATIVE_AR_SESSION_CLASS::Create(config))
{
return {session, ArCreateResult::SUCCESS, ""};
}
return { nullptr, ArCreateResult::FAILED_NOT_SUPPORTED, "No implementation for current system." };
}
catch (const std::exception& e)
{
return { nullptr, ArCreateResult::FAILED_UNKNOWN, e.what() };
}
catch (...) {}
return { nullptr, ArCreateResult::FAILED_UNKNOWN, "Unknown exception while initializing AR system." };
}
ArCreateResult ArSession::CreatePlayback(const std::string& recordingPath, bool autoAdvance)
{
try
{
const auto session = std::make_shared<Playback::ArSessionPlayback>(recordingPath, autoAdvance);
sessions.push_back(session);
return { session, ArCreateResult::SUCCESS, "" };
}
catch (const std::exception& e)
{ // TODO error handling
return { nullptr, ArCreateResult::FAILED_INVALID_PATH, e.what() };
}
catch (...)
{}
return { nullptr, ArCreateResult::FAILED_UNKNOWN, "Unknown exception while initializing AR system." };
}
ArCreateResult ArSession::CreateNetwork(const std::string& serverAddress, std::optional<ArSessionConfig> requestConfig)
{
return { nullptr, ArCreateResult::FAILED_NOT_SUPPORTED, "not yet implemented" };
try
{
const auto session = std::make_shared<Network::ArSessionStream>(serverAddress, requestConfig);
sessions.push_back(session);
return { session, ArCreateResult::SUCCESS, "" };
}
catch (std::exception& e)
{} // TODO error handling
catch (...)
{}
return { nullptr, ArCreateResult::FAILED_UNKNOWN, "Unknown exception while initializing networked AR system." };
}
std::future<ArCreateResult> ArSession::CreateNetworkAsync(const std::string& serverAddress, std::optional<ArSessionConfig> requestConfig)
{
return std::async(&CreateNetwork, serverAddress, requestConfig);
}
std::shared_ptr<ArSession> ArSession::GetPrimarySession()
{
const auto activeSessions = GetActiveSessions();
if (activeSessions.empty()) return nullptr;
return activeSessions[0];
}
std::vector<std::shared_ptr<ArSession>> ArSession::GetActiveSessions()
{
std::vector<std::shared_ptr<ArSession>> activeSessions;
auto it = sessions.begin();
while(it != sessions.end())
{
if (auto activeSession = (*it).lock())
{
activeSessions.push_back(std::move(activeSession));
}
else
{
it = sessions.erase(it);
}
}
return activeSessions;
}
bool ArSession::IsNativeArAvailable()
{
return NATIVE_AR_SESSION_CLASS::IsAvailable();
}
const ArSessionCapabilities& ArSession::GetNativeCapabilities()
{
return NATIVE_AR_SESSION_CLASS::GetCapabilities();
}
}