/* * 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 "ArFrameMetadata.hpp" #include #include #include namespace OpenVulkano::AR { namespace { template T ReadMat(const pugi::xml_node& matrixNode) { T mat(0); auto rowNode = matrixNode.first_child(); for (int row = 0; row < S && rowNode; row++, rowNode = rowNode.next_sibling()) { auto columnNode = rowNode.first_child(); for (int column = 0; column < S && columnNode; column++, columnNode = columnNode.next_sibling()) { mat[column][row] = columnNode.text().as_float(); } } return mat; } template void MatToXML(const glm::mat& mat, std::ostream& stream, const std::string& nl = "\n") { auto nlRow = nl + "\t"; stream << nl; for(int r = 0 ; r < SIZE; r++) { stream << "" << nlRow; for (int c = 0; c < SIZE; c++) { stream << "" << mat[c][r] << ""; } stream << nl << ""; } } template void MatToYaml(const glm::mat& mat, std::ostream& stream, const std::string& nl = "\n") { for(int r = 0 ; r < SIZE; r++) { stream << nl << "- ["; for (int c = 0; c < SIZE; c++) { if (c) stream << ','; stream << ' ' << mat[c][r]; } stream << " ]"; } } } ArFrameMetadata ArFrameMetadata::FromXML(const char* xml, size_t length) { ArFrameMetadata frameData; pugi::xml_document doc; pugi::xml_parse_result result = doc.load_buffer(xml, length); if (!result) throw std::runtime_error("Failed to parse frame metadata"); pugi::xml_node nodeFrame = doc.child("arframe"); pugi::xml_node nodeCamera = nodeFrame.child("camera"); frameData.transformation = ReadMat(nodeCamera.child("transform")); frameData.projection = ReadMat(nodeCamera.child("projection")); pugi::xml_node nodeRes = nodeCamera.child("resolution"); Math::Vector2i resolution = { nodeRes.child("width").text().as_int(), nodeRes.child("height").text().as_int() }; frameData.intrinsic = { ReadMat(nodeCamera.child("intrinsics")), resolution }; frameData.exposureTime = nodeCamera.child("exposureDuration").text().as_float(); frameData.exposureOffset = nodeCamera.child("exposureOffset").text().as_float(); pugi::xml_node nodeLight = nodeFrame.child("light"); frameData.lightIntensity = nodeLight.child("ambientIntensity").text().as_float(); frameData.lightColorTemp = nodeLight.child("ambientColorTemp").text().as_float(); frameData.timestamp = nodeFrame.child("timestamp").text().as_double(); frameData.trackingState = ArTrackingState::GetFromName(nodeFrame.child("trackingState").child("camera").text().as_string()); return frameData; } ArFrameMetadata ArFrameMetadata::FromYaml(const char* xml, size_t length) { ArFrameMetadata frameData; //TODO return frameData; } std::string ArFrameMetadata::ToYaml() const { std::stringstream meta; meta << std::setprecision(std::numeric_limits::digits10); meta << "camera:\n transform: "; MatToYaml(transformation, meta, "\n "); meta << "\n projection"; MatToYaml(projection, meta, "\n "); meta << "\n resolution:\n width: " << intrinsic.GetResolution().x << "\n height: " << intrinsic.GetResolution().y; meta << "\n intrinsics: "; MatToYaml(intrinsic.cameraMatrix, meta, "\n "); meta << "\n exposureDuration: " << exposureTime << "\n exposureOffset: " << exposureOffset; meta << "\ntimestamp: " << timestamp.GetSeconds(); meta << "\ntimestampDepth: " << timestampDepth.GetNanos(); meta << "\ntrackingState: \n camera: " << trackingState.GetName(); meta << "\nlight:\n intensity: " << lightIntensity << "\n colorTemp: " << lightColorTemp; return meta.str(); } std::string ArFrameMetadata::ToXML() const { std::stringstream meta; meta << std::setprecision(std::numeric_limits::digits10); meta << "\n\t\n\t\t"; MatToXML(transformation, meta, "\n\t\t\t"); meta << "\n\t\t\n\t\t"; MatToXML(projection, meta, "\n\t\t\t"); meta << "\n\t\t\n\t\t\n\t\t\t" << intrinsic.GetResolution().x << "\n\t\t\t"; meta << "" << intrinsic.GetResolution().y << "\n\t\t\n\t\t"; MatToXML(intrinsic.cameraMatrix, meta, "\n\t\t\t"); meta << "\n\t\t" << exposureTime << "\n\t\t" << exposureOffset; meta << "\n\t\n\t"; meta << "" << timestamp.GetSeconds() << "\n\t"; meta << "" << timestampDepth.GetSeconds() << "\n\t"; meta << "" << "\n\t\t" << trackingState.GetName() << "" << "\n\t"; meta << "\n\t\t" << lightIntensity << "\n\t\t"; meta << "" << lightColorTemp << "\n\t"; meta << "\n"; return meta.str(); } }