127 lines
4.7 KiB
C++
127 lines
4.7 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 "ArSessionMetadata.hpp"
|
|
#include "Extensions/YamlCppConverters.hpp"
|
|
#include "Host/SystemInfo.hpp"
|
|
#include <pugixml.hpp>
|
|
#include <fmt/format.h>
|
|
#include <filesystem>
|
|
|
|
namespace OpenVulkano::AR
|
|
{
|
|
ArSessionMetadata::ArSessionMetadata()
|
|
: ArSessionMetadata(ArType::UNKNOWN, ArDepthFormat::UNAVAILABLE, {0,0}, { 1920, 1440 }, 60,
|
|
SystemInfo::GetDeviceModelName(), SystemInfo::GetOsNameHumanReadable())
|
|
{}
|
|
|
|
ArSessionMetadata::ArSessionMetadata(ArType type, ArDepthFormat format, Math::Range<uint8_t> confRange, Math::Vector2ui resolution, float frameRate)
|
|
: ArSessionMetadata(type, format, confRange, resolution, frameRate, SystemInfo::GetDeviceModelName(), SystemInfo::GetOsNameHumanReadable())
|
|
{}
|
|
|
|
ArSessionMetadata ArSessionMetadata::FromXML(const std::string& filePath)
|
|
{
|
|
pugi::xml_document doc;
|
|
pugi::xml_parse_result result = doc.load_file(filePath.c_str());
|
|
if (!result) throw std::runtime_error("Failed to read metadata xml file.");
|
|
pugi::xml_node metaNode = doc.child("arPlatformInfo");
|
|
const char* type = metaNode.child("type").text().as_string();
|
|
int minRange = metaNode.child("minConfidence").text().as_int();
|
|
int maxRange = metaNode.child("maxConfidence").text().as_int();
|
|
const char* depthType = metaNode.child("depthType").text().as_string();
|
|
uint32_t resX = 1920, resY = 1440;
|
|
auto resNode = metaNode.child("imageResolution");
|
|
if (!resNode.empty())
|
|
{
|
|
resX = resNode.child("width").text().as_uint();
|
|
resY = resNode.child("height").text().as_uint();
|
|
}
|
|
float frameRate = metaNode.child("frameRate").text().as_float(60);
|
|
uint32_t version = metaNode.child("version").text().as_uint(1);
|
|
std::string device = metaNode.child("device").text().as_string("Unknown");
|
|
std::string os = metaNode.child("os").text().as_string("iOS");
|
|
return { ArType::GetFromHumanReadableName(type),
|
|
ArDepthFormat::GetFromAltName(depthType).value_or(ArDepthFormat::UNAVAILABLE),
|
|
Math::Range<uint8_t>(minRange, maxRange),
|
|
Math::Vector2ui(resX, resY), frameRate, device, os, version
|
|
};
|
|
}
|
|
|
|
ArSessionMetadata ArSessionMetadata::FromYaml(const std::string& filePath)
|
|
{
|
|
YAML::Node meta = YAML::LoadFile(filePath);
|
|
|
|
return {
|
|
ArType::GetFromName(meta["Type"].Scalar()),
|
|
ArDepthFormat::GetFromName(meta["DepthType"].Scalar()).value_or(ArDepthFormat::UNAVAILABLE),
|
|
Math::Range<uint8_t>(meta["MinConfidence"].as<uint8_t>(), meta["MaxConfidence"].as<uint8_t>()),
|
|
meta["Resolution"].as<Math::Vector2ui>(),
|
|
meta["FrameRate"].as<float>(60),
|
|
meta["Device"].as<std::string>("Unknown"), meta["OS"].as<std::string>("Unknown"),
|
|
meta["Vesion"].as<uint32_t>(2)
|
|
};
|
|
}
|
|
|
|
ArSessionMetadata::ArSessionMetadata(const std::string& dirPath)
|
|
{
|
|
std::optional<ArSessionMetadata> metaFromFile;
|
|
std::filesystem::path rPath(dirPath);
|
|
if (!is_directory(rPath)) throw std::runtime_error("Ar recording path must be a directory!");
|
|
std::filesystem::path xmlInfoPath(dirPath + "/arType.info");
|
|
if (std::filesystem::exists(xmlInfoPath))
|
|
{
|
|
metaFromFile = FromXML(xmlInfoPath.string());
|
|
}
|
|
xmlInfoPath = { dirPath + "/ArRecording.xml" };
|
|
if (std::filesystem::exists(xmlInfoPath))
|
|
{
|
|
metaFromFile = FromXML(xmlInfoPath.string());
|
|
}
|
|
std::filesystem::path ymlInfoPath(dirPath + "/ArRecording.yml");
|
|
if (std::filesystem::exists(ymlInfoPath))
|
|
{
|
|
metaFromFile = FromYaml(ymlInfoPath.string());
|
|
}
|
|
if (!metaFromFile) throw std::runtime_error("Ar recording dir is missing platform metadata file!");
|
|
type = metaFromFile->type;
|
|
depthFormat = metaFromFile->depthFormat;
|
|
confidenceRange = metaFromFile->confidenceRange;
|
|
playback = true;
|
|
}
|
|
|
|
std::string ArSessionMetadata::ToXML() const
|
|
{
|
|
return fmt::format(R"(<arPlatformInfo>
|
|
<type>{}</type>
|
|
<minConfidence>{}</minConfidence>
|
|
<maxConfidence>{}</maxConfidence>
|
|
<depthType>{}</depthType>
|
|
<imageResolution><width>{}</width><height>{}</height></imageResolution>
|
|
<frameRate>{}</frameRate>
|
|
<device>{}</device>
|
|
<os>{}</os>
|
|
<version>{}</version>
|
|
</arPlatformInfo>)",
|
|
type.GetHumanReadableName(), static_cast<int>(confidenceRange.min), static_cast<int>(confidenceRange.max),
|
|
depthFormat.GetAltName(), imageResolution.x, imageResolution.y, frameRate, device, os, version);
|
|
}
|
|
|
|
std::string ArSessionMetadata::ToYaml() const
|
|
{
|
|
return fmt::format(R"(Type: {}
|
|
DepthType: {}
|
|
MinConfidence: {}
|
|
MaxConfidence: {}
|
|
Resolution: ({},{})
|
|
FrameRate: {}
|
|
Device: {}
|
|
OS: {}
|
|
Version: {}
|
|
)",
|
|
type.GetName(), depthFormat.GetName(), static_cast<int>(confidenceRange.min), static_cast<int>(confidenceRange.max),
|
|
imageResolution.x, imageResolution.y, frameRate, device, os, version);
|
|
}
|
|
} |