From fd53771ac96e40cf4ea6c5c2c061700f25818634 Mon Sep 17 00:00:00 2001 From: Joakim Kilby Date: Wed, 29 Nov 2023 13:58:22 +0100 Subject: [PATCH] add method & lua binding to convert from binary to ascii recording --- .../openspace/interaction/sessionrecording.h | 2 + src/interaction/sessionrecording.cpp | 115 ++++++++++++++++++ src/interaction/sessionrecording_lua.inl | 7 ++ 3 files changed, 124 insertions(+) diff --git a/include/openspace/interaction/sessionrecording.h b/include/openspace/interaction/sessionrecording.h index 1adfbce109..29d9b24fc6 100644 --- a/include/openspace/interaction/sessionrecording.h +++ b/include/openspace/interaction/sessionrecording.h @@ -593,6 +593,8 @@ public: std::string determineConversionOutFilename(const std::string& filename, DataMode mode); + void binary2ascii(const std::string& filename); + protected: properties::BoolProperty _renderPlaybackInformation; properties::BoolProperty _ignoreRecordedScale; diff --git a/src/interaction/sessionrecording.cpp b/src/interaction/sessionrecording.cpp index 7c5af56778..6869af0db5 100644 --- a/src/interaction/sessionrecording.cpp +++ b/src/interaction/sessionrecording.cpp @@ -2599,6 +2599,120 @@ std::string SessionRecording::determineConversionOutFilename(const std::string& return filenameSansExtension + fileExtension; } +void SessionRecording::binary2ascii(const std::string& filename) { + std::string path = absPath("${RECORDINGS}/" + filename).string(); + std::ifstream infile; + std::stringstream instream; + + try { + readFileIntoStringStream(path, infile, instream); + DataMode mode; + std::string fileVersion; + readPlaybackHeader_stream( + instream, + fileVersion, + mode + ); + + if (mode == DataMode::Unknown) { + LERROR("Unknown data mode for infile."); + } + else if (mode == DataMode::Ascii) { + LWARNING(fmt::format("{} is already in ascii format...", filename)); + return; + } + + std::string out = filename.substr(0, filename.find_last_of(".")) + FileExtensionAscii; + path = absPath("${RECORDINGS}/" + out).string(); + std::ofstream outfile(path); + if (!outfile.is_open() || !outfile.good()) { + LERROR(fmt::format("Failed to open {} for writing.", path)); + } + + outfile << FileHeaderTitle << FileHeaderVersion << DataFormatAsciiTag << "\n"; + + bool ok = true; + while (ok) { + unsigned char frame = readFromPlayback(instream); + if (!instream) { + break; + } + + std::string line; + Timestamps ts; + if (frame == HeaderCameraBinary) { + datamessagestructures::CameraKeyframe ckf; + ok = readSingleKeyframeCamera( + ckf, + ts, + DataMode::Binary, + reinterpret_cast(instream), + line, + -1 + ); + if (ok) { + saveSingleKeyframeCamera( + ckf, + ts, + DataMode::Ascii, + outfile, + _keyframeBuffer + ); + } + } + else if (frame == HeaderTimeBinary) { + datamessagestructures::TimeKeyframe tkf; + ok = readSingleKeyframeTime( + tkf, + ts, + DataMode::Binary, + reinterpret_cast(instream), + line, + -1 + ); + if (ok) { + saveSingleKeyframeTime( + tkf, + ts, + DataMode::Ascii, + outfile, + _keyframeBuffer + ); + } + } + else if (frame == HeaderScriptBinary) { + datamessagestructures::ScriptMessage skf; + ok = readSingleKeyframeScript( + skf, + ts, + DataMode::Binary, + reinterpret_cast(instream), + line, + -1 + ); + if (ok) { + saveSingleKeyframeScript( + skf, + ts, + DataMode::Ascii, + outfile, + _keyframeBuffer + ); + } + } + else { + LERROR(fmt::format("Unknown frame type {}", frame)); + ok = false; + } + } + + LINFO(fmt::format("{} converted to ascii format and saved to {}", filename, out)); + } + catch (std::exception& ex) { + LERROR(ex.what()); + } +} + bool SessionRecording_legacy_0085::convertScript(std::stringstream& inStream, DataMode mode, int lineNum, std::string& inputLine, @@ -2641,6 +2755,7 @@ scripting::LuaLibrary SessionRecording::luaLibrary() { codegen::lua::TogglePlaybackPause, codegen::lua::IsPlayingBack, codegen::lua::IsRecording + codegen::lua::Binary2ascii } }; } diff --git a/src/interaction/sessionrecording_lua.inl b/src/interaction/sessionrecording_lua.inl index 1fb6164865..bdc9e25530 100644 --- a/src/interaction/sessionrecording_lua.inl +++ b/src/interaction/sessionrecording_lua.inl @@ -207,6 +207,13 @@ namespace { return openspace::global::sessionRecording->isRecording(); } +[[codegen::luawrap]] void binary2ascii(std::string fp) { + if (fp.empty()) { + throw ghoul::lua::LuaError("Path string must not be empty"); + } + openspace::global::sessionRecording->binary2ascii(fp); +} + #include "sessionrecording_lua_codegen.cpp" } // namespace