From c03f98717a98104d0e141b4666187beac1afb652 Mon Sep 17 00:00:00 2001 From: GPayne Date: Fri, 30 Aug 2019 16:25:09 -0600 Subject: [PATCH 01/64] Initial non-working version of convert recording format task. --- .../interaction/tasks/convertrecformattask.h | 56 +++++++++ .../tasks/convertrecformattask.cpp | 116 ++++++++++++++++++ 2 files changed, 172 insertions(+) create mode 100644 include/openspace/interaction/tasks/convertrecformattask.h create mode 100644 src/interaction/tasks/convertrecformattask.cpp diff --git a/include/openspace/interaction/tasks/convertrecformattask.h b/include/openspace/interaction/tasks/convertrecformattask.h new file mode 100644 index 0000000000..ae89b4ab3a --- /dev/null +++ b/include/openspace/interaction/tasks/convertrecformattask.h @@ -0,0 +1,56 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2019 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#ifndef __OPENSPACE_CORE___CONVERTRECFORMATTASK___H__ +#define __OPENSPACE_CORE___CONVERTRECFORMATTASK___H__ + +#include + +#include + +#include + +namespace openspace { + +class ConvertRecFormatTask : public Task { +public: + enum class ConversionDirection { + ToAscii = 0, + ToBinary + }; + ConvertRecFormatTask(const ghoul::Dictionary& dictionary); + std::string description() override; + void perform(const Task::ProgressCallback& progressCallback) override; + static documentation::Documentation documentation(); + +private: + std::string _inFilePath; + std::string _outFilePath; + + std::string _valueFunctionLua; +}; + +} // namespace openspace + +#endif //__OPENSPACE_CORE___CONVERTRECFORMATTASK___H__ diff --git a/src/interaction/tasks/convertrecformattask.cpp b/src/interaction/tasks/convertrecformattask.cpp new file mode 100644 index 0000000000..ce8b004353 --- /dev/null +++ b/src/interaction/tasks/convertrecformattask.cpp @@ -0,0 +1,116 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2019 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include +#include +#include + +#include +#include +#include +#include + +namespace { + constexpr const char* KeyConvertToAscii = "ConvertToAscii"; + constexpr const char* KeyConvertToBinary = "ConvertToBinary"; + constexpr const char* KeyInFilePath = "InputFilePath"; + constexpr const char* KeyOutFilePath = "OutputFilePath"; +} + +namespace openspace { + +ConvertRecFormatTask::ConvertRecFormatTask(const ghoul::Dictionary& dictionary) { + openspace::documentation::testSpecificationAndThrow( + documentation(), + dictionary, + "ConvertRecFormatTask" + ); + + _inFilePath = absPath(dictionary.value(KeyInFilePath)); + _outFilePath = absPath(dictionary.value(KeyOutFilePath)); +} + +void ConvertRecFormatTask::perform(const Task::ProgressCallback& progressCallback) { + +} + +void ConvertRecFormatTask::convert() { + RecordedDataMode type = formatType(); + + if (type == RecordedDataMode::Ascii) { + convertToBinary(); + } + else if (type == RecordedDataMode::Binary) { + convertToAscii(); + } + else { + //Add error output for file type not recognized + } +} + +RecordedDataMode ConvertRecFormatTask::formatType() { + //Read file at _inFilePath + + //Read first line + + //First verify that the line starts with the valid string + + //Get last character which should be either 'A' or 'B', and return Ascii or Binary based on this. +} + +void ConvertRecFormatTask::convertToAscii() { + +} + +void ConvertRecFormatTask::convertToBinary() { + +} + +documentation::Documentation ConvertRecFormatTask::documentation() { + using namespace documentation; + return { + "ConvertRecFormatTask", + "convert_format_task", + { + { + "Type", + new StringEqualVerifier("ConvertRecFormatTask"), + Optional::No, + "The type of this task", + }, + { + KeyInFilePath, + new StringAnnotationVerifier("A valid filename to convert"), + Optional::No, + "The filename to convert to the opposite format.", + }, + { + KeyOutFilePath, + new StringAnnotationVerifier("A valid output filename"), + Optional::No, + "The filename containing the converted result.", + }, + }, + }; +} From 40526b11a2918e270cb2c16a72245142d17ebb5f Mon Sep 17 00:00:00 2001 From: GPayne Date: Fri, 30 Aug 2019 16:57:48 -0600 Subject: [PATCH 02/64] Added command to save current delta time when recording starts. --- src/interaction/sessionrecording.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/interaction/sessionrecording.cpp b/src/interaction/sessionrecording.cpp index b46206e6d7..73000cc2fd 100644 --- a/src/interaction/sessionrecording.cpp +++ b/src/interaction/sessionrecording.cpp @@ -168,8 +168,15 @@ bool SessionRecording::startRecording(const std::string& filename) { } _recordFile << '\n'; + //Record the current delta time so this is preserved in recording + double currentDeltaTime = global::timeManager.deltaTime(); + std::string scriptCommandForInitializingDeltaTime = "openspace.time.setDeltaTime("; + scriptCommandForInitializingDeltaTime << currentDeltaTime << ");"; + saveScriptKeyframe(scriptCommandForInitializingDeltaTime); + LINFO("Session recording started"); _timestampRecordStarted = global::windowDelegate.applicationTime(); + return true; } From 1e426f3c4604924cb3bd8589869c3049f9f97e41 Mon Sep 17 00:00:00 2001 From: GPayne Date: Wed, 4 Sep 2019 11:10:08 -0600 Subject: [PATCH 03/64] Prevent changing the simulation time rate during playback --- include/openspace/util/timemanager.h | 1 + src/interaction/sessionrecording.cpp | 5 +++-- src/util/timemanager.cpp | 13 ++++++++++--- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/include/openspace/util/timemanager.h b/include/openspace/util/timemanager.h index 523ec5da5b..fb9d5293e2 100644 --- a/include/openspace/util/timemanager.h +++ b/include/openspace/util/timemanager.h @@ -105,6 +105,7 @@ public: void removeTimeChangeCallback(CallbackHandle handle); void removeDeltaTimeChangeCallback(CallbackHandle handle); void triggerPlaybackStart(); + void stopPlayback(); void removeTimeJumpCallback(CallbackHandle handle); void removeTimelineChangeCallback(CallbackHandle handle); diff --git a/src/interaction/sessionrecording.cpp b/src/interaction/sessionrecording.cpp index 73000cc2fd..0c51e6ad23 100644 --- a/src/interaction/sessionrecording.cpp +++ b/src/interaction/sessionrecording.cpp @@ -170,8 +170,8 @@ bool SessionRecording::startRecording(const std::string& filename) { //Record the current delta time so this is preserved in recording double currentDeltaTime = global::timeManager.deltaTime(); - std::string scriptCommandForInitializingDeltaTime = "openspace.time.setDeltaTime("; - scriptCommandForInitializingDeltaTime << currentDeltaTime << ");"; + std::string scriptCommandForInitializingDeltaTime = + "openspace.time.setDeltaTime(" + std::to_string(currentDeltaTime) + ");"; saveScriptKeyframe(scriptCommandForInitializingDeltaTime); LINFO("Session recording started"); @@ -360,6 +360,7 @@ void SessionRecording::stopPlayback() { void SessionRecording::cleanUpPlayback() { global::navigationHandler.stopPlayback(); + global::timeManager.stopPlayback(); Camera* camera = global::navigationHandler.camera(); ghoul_assert(camera != nullptr, "Camera must not be nullptr"); diff --git a/src/util/timemanager.cpp b/src/util/timemanager.cpp index d8e920d2a7..430e4035b5 100644 --- a/src/util/timemanager.cpp +++ b/src/util/timemanager.cpp @@ -103,6 +103,10 @@ TimeManager::TimeManager() } void TimeManager::interpolateTime(double targetTime, double durationSeconds) { + if (_playbackModeEnabled) { + return; + } + ghoul_precondition(durationSeconds > 0.f, "durationSeconds must be positive"); const double now = global::windowDelegate.applicationTime(); @@ -275,8 +279,7 @@ void TimeManager::progressTime(double dt) { // and time is not paused, just advance time. _deltaTime = _targetDeltaTime; _currentTime.data().advanceTime(dt * _deltaTime); - _playbackModeEnabled = false; - } + } if (hasPastKeyframes) { _latestConsumedTimestamp = lastPastKeyframe->timestamp; @@ -456,6 +459,10 @@ void TimeManager::triggerPlaybackStart() { _playbackModeEnabled = true; } +void TimeManager::stopPlayback() { + _playbackModeEnabled = false; +} + void TimeManager::removeTimeJumpCallback(CallbackHandle handle) { const auto it = std::find_if( _timeJumpCallbacks.begin(), @@ -520,7 +527,7 @@ double TimeManager::targetDeltaTime() const { void TimeManager::interpolateDeltaTime(double newDeltaTime, double interpolationDuration) { - if (newDeltaTime == _targetDeltaTime) { + if (newDeltaTime == _targetDeltaTime || _playbackModeEnabled) { return; } From b375205c1a5f7b63745eaafeec792bbd6b84d32e Mon Sep 17 00:00:00 2001 From: GPayne Date: Thu, 5 Sep 2019 12:42:01 -0600 Subject: [PATCH 04/64] Undo on recently-added changes that restricted time manipulation during playback. --- src/util/timemanager.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/util/timemanager.cpp b/src/util/timemanager.cpp index 430e4035b5..3a03fd3cc0 100644 --- a/src/util/timemanager.cpp +++ b/src/util/timemanager.cpp @@ -103,10 +103,6 @@ TimeManager::TimeManager() } void TimeManager::interpolateTime(double targetTime, double durationSeconds) { - if (_playbackModeEnabled) { - return; - } - ghoul_precondition(durationSeconds > 0.f, "durationSeconds must be positive"); const double now = global::windowDelegate.applicationTime(); @@ -279,7 +275,7 @@ void TimeManager::progressTime(double dt) { // and time is not paused, just advance time. _deltaTime = _targetDeltaTime; _currentTime.data().advanceTime(dt * _deltaTime); - } + } if (hasPastKeyframes) { _latestConsumedTimestamp = lastPastKeyframe->timestamp; @@ -527,7 +523,7 @@ double TimeManager::targetDeltaTime() const { void TimeManager::interpolateDeltaTime(double newDeltaTime, double interpolationDuration) { - if (newDeltaTime == _targetDeltaTime || _playbackModeEnabled) { + if (newDeltaTime == _targetDeltaTime) { return; } From 5b4ecf2b62d550a5f3ba1920ca96a356978e5755 Mon Sep 17 00:00:00 2001 From: GPayne Date: Thu, 5 Sep 2019 14:56:11 -0600 Subject: [PATCH 05/64] Fixed timestamp problem with time rate script at start of recording --- src/interaction/sessionrecording.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/interaction/sessionrecording.cpp b/src/interaction/sessionrecording.cpp index 0c51e6ad23..3ae0695f60 100644 --- a/src/interaction/sessionrecording.cpp +++ b/src/interaction/sessionrecording.cpp @@ -168,14 +168,15 @@ bool SessionRecording::startRecording(const std::string& filename) { } _recordFile << '\n'; + _timestampRecordStarted = global::windowDelegate.applicationTime(); + //Record the current delta time so this is preserved in recording double currentDeltaTime = global::timeManager.deltaTime(); std::string scriptCommandForInitializingDeltaTime = - "openspace.time.setDeltaTime(" + std::to_string(currentDeltaTime) + ");"; + "openspace.time.setDeltaTime(" + std::to_string(currentDeltaTime) + ")"; saveScriptKeyframe(scriptCommandForInitializingDeltaTime); LINFO("Session recording started"); - _timestampRecordStarted = global::windowDelegate.applicationTime(); return true; } From 299c4f10c43c9c08eb5425e5d3db0ef0c9e64d81 Mon Sep 17 00:00:00 2001 From: GPayne Date: Fri, 11 Oct 2019 11:45:55 -0600 Subject: [PATCH 06/64] Added some file handling to record conversion tasks --- .../openspace/interaction/sessionrecording.h | 8 +++ .../interaction/tasks/convertrecformattask.h | 13 ++++ src/interaction/sessionrecording.cpp | 21 ------ .../tasks/convertrecformattask.cpp | 71 +++++++++++++++---- 4 files changed, 77 insertions(+), 36 deletions(-) diff --git a/include/openspace/interaction/sessionrecording.h b/include/openspace/interaction/sessionrecording.h index 26c5f5a094..82e22f38c2 100644 --- a/include/openspace/interaction/sessionrecording.h +++ b/include/openspace/interaction/sessionrecording.h @@ -45,6 +45,14 @@ public: Playback }; + const std::string FileHeaderTitle = "OpenSpace_record/playback"; + constexpr const size_t FileHeaderVersionLength = 5; + constexpr const char FileHeaderVersion[FileHeaderVersionLength] = { + '0', '0', '.', '8', '5' + }; + constexpr const char DataFormatAsciiTag = 'A'; + constexpr const char DataFormatBinaryTag = 'B'; + using CallbackHandle = int; using StateChangeCallback = std::function; diff --git a/include/openspace/interaction/tasks/convertrecformattask.h b/include/openspace/interaction/tasks/convertrecformattask.h index ae89b4ab3a..65c6aeef28 100644 --- a/include/openspace/interaction/tasks/convertrecformattask.h +++ b/include/openspace/interaction/tasks/convertrecformattask.h @@ -31,6 +31,13 @@ #include +namespace { + constexpr const char* KeyConvertToAscii = "ConvertToAscii"; + constexpr const char* KeyConvertToBinary = "ConvertToBinary"; + constexpr const char* KeyInFilePath = "InputFilePath"; + constexpr const char* KeyOutFilePath = "OutputFilePath"; +} + namespace openspace { class ConvertRecFormatTask : public Task { @@ -40,13 +47,19 @@ public: ToBinary }; ConvertRecFormatTask(const ghoul::Dictionary& dictionary); + ~ConvertRecFormatTask(); std::string description() override; void perform(const Task::ProgressCallback& progressCallback) override; static documentation::Documentation documentation(); private: + void convertToAscii(); + void convertToBinary(); + std::string _inFilePath; std::string _outFilePath; + std::ifstream _iFile; + std::ifstream _oFile; std::string _valueFunctionLua; }; diff --git a/src/interaction/sessionrecording.cpp b/src/interaction/sessionrecording.cpp index 0c51e6ad23..1eb8fd2d03 100644 --- a/src/interaction/sessionrecording.cpp +++ b/src/interaction/sessionrecording.cpp @@ -46,14 +46,6 @@ namespace { constexpr const char* _loggerCat = "SessionRecording"; constexpr const bool UsingTimeKeyframes = false; - const std::string FileHeaderTitle = "OpenSpace_record/playback"; - constexpr const size_t FileHeaderVersionLength = 5; - constexpr const char FileHeaderVersion[FileHeaderVersionLength] = { - '0', '0', '.', '8', '5' - }; - constexpr const char DataFormatAsciiTag = 'A'; - constexpr const char DataFormatBinaryTag = 'B'; - template T readFromPlayback(std::ifstream& stream) { @@ -979,19 +971,6 @@ void SessionRecording::playbackScript() { } } double timeRef = appropriateTimestamp(timeOs, timeRec, timeSim); - //timeRef = getEquivalentSimulationTime(timeOs, timeRec, timeSim); - - //Call script scheduler with this new script entry - //std::string timeDescription = SpiceManager::ref().dateFromEphemerisTime( - // timeRef, - // "YYYY MON DD HR:MN:SC.###" - //); - //ghoul::Dictionary scriptDict(ghoul::Dictionary{ - // { KeyTime, timeDescription }, - // { KeyForwardScript, pbFrame._script} - //} - // ); - //global::scriptScheduler.loadScripts({ { "1", scriptDict } }); addKeyframe(timeRef, pbFrame._script); } diff --git a/src/interaction/tasks/convertrecformattask.cpp b/src/interaction/tasks/convertrecformattask.cpp index ce8b004353..1425e04e51 100644 --- a/src/interaction/tasks/convertrecformattask.cpp +++ b/src/interaction/tasks/convertrecformattask.cpp @@ -30,13 +30,11 @@ #include #include #include +#include namespace { - constexpr const char* KeyConvertToAscii = "ConvertToAscii"; - constexpr const char* KeyConvertToBinary = "ConvertToBinary"; - constexpr const char* KeyInFilePath = "InputFilePath"; - constexpr const char* KeyOutFilePath = "OutputFilePath"; -} + constexpr const char* _loggerCat = "ConvertRecFormatTask"; +} // namespace namespace openspace { @@ -49,6 +47,20 @@ ConvertRecFormatTask::ConvertRecFormatTask(const ghoul::Dictionary& dictionary) _inFilePath = absPath(dictionary.value(KeyInFilePath)); _outFilePath = absPath(dictionary.value(KeyOutFilePath)); + + ghoul_assert(FileSys.fileExists(_inFilePath), "The filename must exist"); + if (!FileSys.fileExists(_inFilePath)) { + LERROR(fmt::format("Failed to load session recording file: {}", _inFilePath)); + //throw ghoul::FileNotFoundError(_inFilePath); + } + + _iFile.exceptions(std::ofstream::failbit | std::ofstream::badbit); + _iFile.open(_inFilePath); +} + +ConvertRecFormatTask::~ConvertRecFormatTask() { + _iFile.close(); + _oFile.close(); } void ConvertRecFormatTask::perform(const Task::ProgressCallback& progressCallback) { @@ -56,35 +68,64 @@ void ConvertRecFormatTask::perform(const Task::ProgressCallback& progressCallbac } void ConvertRecFormatTask::convert() { - RecordedDataMode type = formatType(); + interaction::RecordedDataMode type = formatType(); - if (type == RecordedDataMode::Ascii) { + if (type == interaction::RecordedDataMode::Ascii) { convertToBinary(); } - else if (type == RecordedDataMode::Binary) { + else if (type == interaction::RecordedDataMode::Binary) { convertToAscii(); } else { //Add error output for file type not recognized + LERROR("Session recording file unrecognized format type."); } } RecordedDataMode ConvertRecFormatTask::formatType() { - //Read file at _inFilePath + const std::string expectedHeader = "OpenSpace_record/playback"; + std::string line; + //Get first line, which is ASCII regardless of format + std::getline(_iFile, line); - //Read first line - - //First verify that the line starts with the valid string - - //Get last character which should be either 'A' or 'B', and return Ascii or Binary based on this. + if (line.substr(0, interaction::FileHeaderTitle.length()) + != interaction::FileHeaderTitle) + { + LERROR(fmt::format("Session recording file {} does not have expected header.", _inFilePath)); + return RecordedDataMode::Binary + 1; + } + else { + if (line.back() == DataFormatAsciiTag) { + return RecordedDataMode::Ascii; + } + else if (line.back() == DataFormatBinaryTag) { + return RecordedDataMode::Binary; + } + else { + return RecordedDataMode::Binary + 1; + } + } } void ConvertRecFormatTask::convertToAscii() { - + _outFilePath = addFileSuffix(_inFilePath, "_ascii"); } void ConvertRecFormatTask::convertToBinary() { + _outFilePath = addFileSuffix(_inFilePath, "_binary"); +} +std::string ConvertRecFormatTask::addFileSuffix(const std::string& filePath, + const std::string& suffix) +{ + size_t lastdot = filename.find_last_of("."); + std::string extension = filePath.substr(0, lastdot); + if (lastdot == std::string::npos) { + return filePath + suffix; + } + else { + return filePath.substr(0, lastdot) + suffix + extension; + } } documentation::Documentation ConvertRecFormatTask::documentation() { From 27ef369338991affeb6687703d5027e79fd8d49d Mon Sep 17 00:00:00 2001 From: GPayne Date: Thu, 17 Oct 2019 18:20:37 -0600 Subject: [PATCH 07/64] Separated playback keyframe extraction into steps (file read & parse) --- .../openspace/interaction/keyframenavigator.h | 8 ++ .../openspace/interaction/sessionrecording.h | 30 ++++ include/openspace/network/messagestructures.h | 16 +++ src/interaction/sessionrecording.cpp | 135 +++++++++--------- 4 files changed, 120 insertions(+), 69 deletions(-) diff --git a/include/openspace/interaction/keyframenavigator.h b/include/openspace/interaction/keyframenavigator.h index a241815c2c..77783d6bd4 100644 --- a/include/openspace/interaction/keyframenavigator.h +++ b/include/openspace/interaction/keyframenavigator.h @@ -54,6 +54,14 @@ public: std::string focusNode; float scale; bool followFocusNodeRotation; + + CameraPose(const openspace::datamessagestructures::CameraKeyframe& kf) { + position = kf._position; + rotation = kf._rotation; + focusNode = kf._focusNode; + scale = kf._scale; + followFocusNodeRotation = kf._followNodeRotation; + } }; /** diff --git a/include/openspace/interaction/sessionrecording.h b/include/openspace/interaction/sessionrecording.h index 82e22f38c2..025a91a7d7 100644 --- a/include/openspace/interaction/sessionrecording.h +++ b/include/openspace/interaction/sessionrecording.h @@ -45,6 +45,12 @@ public: Playback }; + struct timestamps { + double timeOs; + double timeRec; + double timeSim; + }; + const std::string FileHeaderTitle = "OpenSpace_record/playback"; constexpr const size_t FileHeaderVersionLength = 5; constexpr const char FileHeaderVersion[FileHeaderVersionLength] = { @@ -216,6 +222,30 @@ public: */ std::vector playbackList() const; + /** + * Reads a camera keyframe from a binary format playback file, and populates input + * references with the parameters of the keyframe. + * + * \param times reference to a timestamps structure which contains recorded times + * \param kf reference to a camera keyframe which contains camera details + * \param file an ifstream reference to the playback file being read + * \param lineN keyframe number in playback file where this keyframe resides + */ + static void readCameraKeyframeBinary(timestamps& times, + datamessagestructures::CameraKeyframe& kf, std::ifstream& file, int lineN); + + /** + * Reads a camera keyframe from an ascii format playback file, and populates input + * references with the parameters of the keyframe. + * + * \param times reference to a timestamps structure which contains recorded times + * \param kf reference to a camera keyframe which contains camera details + * \param filenameRead a string containing the playback filename + * \param lineN line number in playback file where this keyframe resides + */ + static void readCameraKeyframeAscii(timestamps& times, + datamessagestructures::CameraKeyframe& kf, std::string filenameRead, int lineN); + private: enum class RecordedType { Camera = 0, diff --git a/include/openspace/network/messagestructures.h b/include/openspace/network/messagestructures.h index d1e60f7bb3..aa873d8ca4 100644 --- a/include/openspace/network/messagestructures.h +++ b/include/openspace/network/messagestructures.h @@ -233,6 +233,22 @@ struct CameraKeyframe { sizeof(_timestamp) ); }; + + void read(std::istringstream* iss) { + std::string rotationFollowing; + + iss >> _position.x + >> _position.y + >> _position.z + >> _rotation.x + >> _rotation.y + >> _rotation.z + >> _rotation.w + >> _scale + >> rotationFollowing + >> _focusNode; + _followNodeRotation = (rotationFollowing == "F"); + }; }; struct TimeKeyframe { diff --git a/src/interaction/sessionrecording.cpp b/src/interaction/sessionrecording.cpp index 37a9303403..091c7fe1d1 100644 --- a/src/interaction/sessionrecording.cpp +++ b/src/interaction/sessionrecording.cpp @@ -781,84 +781,81 @@ double SessionRecording::fixedDeltaTimeDuringFrameOutput() const { } void SessionRecording::playbackCamera() { - double timeOs; - double timeRec; - double timeSim; - std::string rotationFollowing; - interaction::KeyframeNavigator::CameraPose pbFrame; + timestamps times; datamessagestructures::CameraKeyframe kf; + if (_recordingDataMode == RecordedDataMode::Binary) { - timeOs = readFromPlayback(_playbackFile); - timeRec = readFromPlayback(_playbackFile); - timeSim = readFromPlayback(_playbackFile); - try { - kf.read(&_playbackFile); - } - catch (std::bad_alloc&) { - LERROR(fmt::format( - "Allocation error with camera playback from keyframe entry {}", - _playbackLineNum - 1 - )); - return; - } - catch (std::length_error&) { - LERROR(fmt::format( - "length_error with camera playback from keyframe entry {}", - _playbackLineNum - 1 - )); - return; - } - - timeOs = kf._timestamp; - - pbFrame.focusNode = kf._focusNode; - pbFrame.position = kf._position; - pbFrame.rotation = kf._rotation; - pbFrame.scale = kf._scale; - pbFrame.followFocusNodeRotation = kf._followNodeRotation; - - if (!_playbackFile) { - LINFO(fmt::format( - "Error reading camera playback from keyframe entry {}", - _playbackLineNum - 1 - )); - return; - } + readCameraKeyframeBinary(times, kf, _playbackFile, _playbackLineNum); } else { - std::istringstream iss(_playbackLineParsing); - std::string entryType; - iss >> entryType; - iss >> timeOs >> timeRec >> timeSim; - iss >> pbFrame.position.x - >> pbFrame.position.y - >> pbFrame.position.z - >> pbFrame.rotation.x - >> pbFrame.rotation.y - >> pbFrame.rotation.z - >> pbFrame.rotation.w - >> pbFrame.scale - >> rotationFollowing - >> pbFrame.focusNode; - if (iss.fail() || !iss.eof()) { - LERROR(fmt::format( - "Error parsing camera line {} of playback file", _playbackLineNum - )); - return; - } - pbFrame.followFocusNodeRotation = (rotationFollowing == "F"); + readCameraKeyframeAscii(times, kf, _playbackLineParsing, _playbackLineNum); } - if (_setSimulationTimeWithNextCameraKeyframe) { - global::timeManager.setTimeNextFrame(Time(timeSim)); - _setSimulationTimeWithNextCameraKeyframe = false; - _saveRenderingCurrentRecordedTime = timeRec; - } - double timeRef = appropriateTimestamp(timeOs, timeRec, timeSim); - //global::navigationHandler.keyframeNavigator().addKeyframe(timeRef, pbFrame); + if (_setSimulationTimeWithNextCameraKeyframe) { + global::timeManager.setTimeNextFrame(Time(times.timeSim)); + _setSimulationTimeWithNextCameraKeyframe = false; + _saveRenderingCurrentRecordedTime = times.timeRec; + } + double timeRef = appropriateTimestamp(times.timeOs, times.timeRec, times.timeSim); + + interaction::KeyframeNavigator::CameraPose pbFrame(kf); addKeyframe(timeRef, pbFrame); } +static void SessionRecording::readCameraKeyframeBinary(timestamps& times, + datamessagestructures::CameraKeyframe& kf, + std::ifstream& file, int lineN) +{ + times.timeOs = readFromPlayback(file); + times.timeRec = readFromPlayback(file); + times.timeSim = readFromPlayback(file); + try { + kf.read(&file); + } + catch (std::bad_alloc&) { + LERROR(fmt::format( + "Allocation error with camera playback from keyframe entry {}", + lineN - 1 + )); + return; + } + catch (std::length_error&) { + LERROR(fmt::format( + "length_error with camera playback from keyframe entry {}", + lineN - 1 + )); + return; + } + times.timeOs = kf._timestamp; + + if (!file) { + LINFO(fmt::format( + "Error reading camera playback from keyframe entry {}", + lineN - 1 + )); + return; + } +} + +static void SessionRecording::readCameraKeyframeAscii(timestamps& times, + datamessagestructures::CameraKeyframe& kf, + std::string filenameRead, + int lineN) +{ + std::string rotationFollowing; + std::string entryType; + + std::istringstream iss(filenameRead); + iss >> entryType; + iss >> times.timeOs >> times.timeRec >> times.timeSim; + kf.read(&iss); + + if (iss.fail() || !iss.eof()) { + LERROR(fmt::format("Error parsing camera line {} of playback file", lineN)); + return; + } +} + void SessionRecording::playbackTimeChange() { double timeOs; double timeRec; From a549993727a314305fc895a2cf41892f3c9df3fc Mon Sep 17 00:00:00 2001 From: GPayne Date: Wed, 23 Oct 2019 18:02:20 -0600 Subject: [PATCH 08/64] Finished time and script keyframe types into separate read & parse steps --- .../openspace/interaction/sessionrecording.h | 50 ++++ include/openspace/network/messagestructures.h | 24 ++ src/interaction/sessionrecording.cpp | 231 ++++++++++-------- 3 files changed, 203 insertions(+), 102 deletions(-) diff --git a/include/openspace/interaction/sessionrecording.h b/include/openspace/interaction/sessionrecording.h index 025a91a7d7..7cf6905312 100644 --- a/include/openspace/interaction/sessionrecording.h +++ b/include/openspace/interaction/sessionrecording.h @@ -246,6 +246,56 @@ public: static void readCameraKeyframeAscii(timestamps& times, datamessagestructures::CameraKeyframe& kf, std::string filenameRead, int lineN); + /** + * Reads a time keyframe from a binary format playback file, and populates input + * references with the parameters of the keyframe. + * + * \param times reference to a timestamps structure which contains recorded times + * \param kf reference to a time keyframe which contains time details + * \param file an ifstream reference to the playback file being read + * \param lineN keyframe number in playback file where this keyframe resides + */ + static void SessionRecording::readTimeKeyframeBinary(timestamps& times, + datamessagestructures::TimeKeyframe& kf, std::ifstream& file, int lineN); + + /** + * Reads a time keyframe from an ascii format playback file, and populates input + * references with the parameters of the keyframe. + * + * \param times reference to a timestamps structure which contains recorded times + * \param kf reference to a time keyframe which contains time details + * \param filenameRead a string containing the playback filename + * \param lineN line number in playback file where this keyframe resides + */ + static void SessionRecording::readTimeKeyframeAscii(timestamps& times, + datamessagestructures::TimeKeyframe& kf, std::string filenameRead, int lineN); + + /** + * Reads a script keyframe from a binary format playback file, and populates input + * references with the parameters of the keyframe. + * + * \param times reference to a timestamps structure which contains recorded times + * \param kf reference to a script keyframe which contains the size of the script + * (in chars) and the text itself + * \param file an ifstream reference to the playback file being read + * \param lineN keyframe number in playback file where this keyframe resides + */ + static void SessionRecording::readScriptKeyframeBinary(timestamps& times, + datamessagestructures::ScriptMessage& kf, std::ifstream& file, int lineN); + + /** + * Reads a script keyframe from an ascii format playback file, and populates input + * references with the parameters of the keyframe. + * + * \param times reference to a timestamps structure which contains recorded times + * \param kf reference to a script keyframe which contains the size of the script + * (in chars) and the text itself + * \param filenameRead a string containing the playback filename + * \param lineN line number in playback file where this keyframe resides + */ + static void SessionRecording::readScriptKeyframeAscii(timestamps& times, + datamessagestructures::ScriptMessage& kf, std::string filenameRead, int lineN); + private: enum class RecordedType { Camera = 0, diff --git a/include/openspace/network/messagestructures.h b/include/openspace/network/messagestructures.h index aa873d8ca4..8b9d72cc64 100644 --- a/include/openspace/network/messagestructures.h +++ b/include/openspace/network/messagestructures.h @@ -290,6 +290,16 @@ struct TimeKeyframe { sizeof(TimeKeyframe) ); }; + + void read(std::istringstream* iss) { + std::string paused, jump; + + iss >> _dt + >> paused + >> jump; + _paused = (paused == "P"); + _requiresTimeJump = (jump == "J"); + }; }; struct TimeTimeline { @@ -404,6 +414,20 @@ struct ScriptMessage { _script.erase(); _script = temp.data(); }; + + void read(std::istringstream* iss) { + int numScriptLines; + iss >> numScriptLines; + std::string tmpReadbackScript; + _script.erase(); + for (unsigned int i = 0; i < numScriptLines; ++i) { + std::getline(iss, tmpReadbackScript); + _script.append(tmpReadbackScript); + if (i < (numScriptLines - 1)) { + _script.append("\n"); + } + } + }; }; } // namespace openspace::messagestructures diff --git a/src/interaction/sessionrecording.cpp b/src/interaction/sessionrecording.cpp index 091c7fe1d1..656298d65a 100644 --- a/src/interaction/sessionrecording.cpp +++ b/src/interaction/sessionrecording.cpp @@ -803,7 +803,7 @@ void SessionRecording::playbackCamera() { } static void SessionRecording::readCameraKeyframeBinary(timestamps& times, - datamessagestructures::CameraKeyframe& kf, + datamessagestructures::CameraKeyframe& kf, std::ifstream& file, int lineN) { times.timeOs = readFromPlayback(file); @@ -838,7 +838,7 @@ static void SessionRecording::readCameraKeyframeBinary(timestamps& times, } static void SessionRecording::readCameraKeyframeAscii(timestamps& times, - datamessagestructures::CameraKeyframe& kf, + datamessagestructures::CameraKeyframe& kf, std::string filenameRead, int lineN) { @@ -857,119 +857,146 @@ static void SessionRecording::readCameraKeyframeAscii(timestamps& times, } void SessionRecording::playbackTimeChange() { - double timeOs; - double timeRec; - double timeSim; - datamessagestructures::TimeKeyframe pbFrame; + timestamps times; + datamessagestructures::TimeKeyframe kf; + if (_recordingDataMode == RecordedDataMode::Binary) { - timeOs = readFromPlayback(_playbackFile); - timeRec = readFromPlayback(_playbackFile); - timeSim = readFromPlayback(_playbackFile); - pbFrame._dt = readFromPlayback(_playbackFile); - pbFrame._paused = readFromPlayback(_playbackFile); - pbFrame._requiresTimeJump = readFromPlayback(_playbackFile); - - if (!_playbackFile) { - LERROR(fmt::format( - "Error reading time playback from keyframe entry {}", _playbackLineNum - 1 - )); - return; - } + readTimeKeyframeBinary(times, kf, _playbackFile, _playbackLineNum); } else { - std::istringstream iss(_playbackLineParsing); - std::string entryType; - //double timeRef; - std::string paused, jump; - iss >> entryType; - iss >> timeOs >> timeRec >> timeSim; - iss >> pbFrame._dt - >> paused - >> jump; - if (iss.fail() || !iss.eof()) { - LERROR(fmt::format( - "Error parsing time line {} of playback file", _playbackLineNum - )); - return; - } - pbFrame._paused = (paused == "P"); - pbFrame._requiresTimeJump = (jump == "J"); + readTimeKeyframeAscii(times, kf, _playbackLineParsing, _playbackLineNum); } - pbFrame._timestamp = equivalentApplicationTime(timeOs, timeRec, timeSim); + kf._timestamp = equivalentApplicationTime(times.timeOs, times.timeRec, times.timeSim); - pbFrame._time = pbFrame._timestamp + _timestampApplicationStarted_simulation; + kf._time = kf._timestamp + _timestampApplicationStarted_simulation; //global::timeManager.addKeyframe(timeRef, pbFrame._timestamp); //_externInteract.timeInteraction(pbFrame); - addKeyframe(pbFrame._timestamp, pbFrame); + addKeyframe(kf._timestamp, kf); +} + +static void SessionRecording::readTimeKeyframeBinary(timestamps& times, + datamessagestructures::TimeKeyframe& kf, + std::ifstream& file, int lineN) +{ + times.timeOs = readFromPlayback(file); + times.timeRec = readFromPlayback(file); + times.timeSim = readFromPlayback(file); + + try { + kf.read(&file); + } + catch (std::bad_alloc&) { + LERROR(fmt::format( + "Allocation error with time playback from keyframe entry {}", + lineN - 1 + )); + return; + } + catch (std::length_error&) { + LERROR(fmt::format( + "length_error with time playback from keyframe entry {}", + lineN - 1 + )); + return; + } + + if (!file) { + LERROR(fmt::format( + "Error reading time playback from keyframe entry {}", lineN - 1 + )); + return; + } +} + +static void SessionRecording::readTimeKeyframeAscii(timestamps& times, + datamessagestructures::TimeKeyframe& kf, + std::string filenameRead, + int lineN) +{ + std::string entryType; + + std::istringstream iss(filenameRead); + iss >> entryType; + iss >> times.timeOs >> times.timeRec >> times.timeSim; + kf.read(&iss); + + if (iss.fail() || !iss.eof()) { + LERROR(fmt::format( + "Error parsing time line {} of playback file", _playbackLineNum + )); + return; + } } void SessionRecording::playbackScript() { - double timeOs; - double timeRec; - double timeSim; - unsigned int numScriptLines; - datamessagestructures::ScriptMessage pbFrame; + timestamps times; + datamessagestructures::ScriptMessage kf; if (_recordingDataMode == RecordedDataMode::Binary) { - timeOs = readFromPlayback(_playbackFile); - timeRec = readFromPlayback(_playbackFile); - timeSim = readFromPlayback(_playbackFile); - try { - pbFrame._script = readFromPlayback(_playbackFile); - } - catch (std::bad_alloc&) { - LERROR(fmt::format( - "Allocation error with script playback from keyframe entry {}", - _playbackLineNum - 1 - )); - return; - } - catch (std::length_error&) { - LERROR(fmt::format( - "length_error with script playback from keyframe entry {}", - _playbackLineNum - 1 - )); - return; - } - - if (!_playbackFile) { - LERROR(fmt::format( - "Error reading script playback from keyframe entry {}", - _playbackLineNum - 1 - )); - return; - } + readScriptKeyframeBinary(times, kf, _playbackFile, _playbackLineNum); } else { - std::istringstream iss(_playbackLineParsing); - std::string entryType; - std::string tmpReadbackScript; - - iss >> entryType; - iss >> timeOs >> timeRec >> timeSim; - iss >> numScriptLines; - std::getline(iss, tmpReadbackScript); //iss >> tmpReadbackScript; - pbFrame._script.append(tmpReadbackScript); - if (iss.fail()) { - LERROR(fmt::format( - "Error parsing script line {} of playback file", _playbackLineNum - )); - return; - } else if (!iss.eof()) { - LERROR(fmt::format( - "Did not find an EOL at line {} of playback file", _playbackLineNum - )); - return; - } - if (numScriptLines > 1) { - //Now loop to read any subsequent lines if is a multi-line script - for (unsigned int i = 1; i < numScriptLines; ++i) { - pbFrame._script.append("\n"); - std::getline(_playbackFile, tmpReadbackScript); - pbFrame._script.append(tmpReadbackScript); - } - } + readScriptKeyframeAscii(times, kf, _playbackLineParsing, _playbackLineNum); + } + + double timeRef = appropriateTimestamp(times.timeOs, times.timeRec, times.timeSim); + addKeyframe(timeRef, kf._script); +} + +static void SessionRecording::readScriptKeyframeBinary(timestamps& times, + datamessagestructures::ScriptMessage& kf, + std::ifstream& file, int lineN) +{ + times.timeOs = readFromPlayback(file); + times.timeRec = readFromPlayback(file); + times.timeSim = readFromPlayback(file); + + try { + kf.read(&file); + } + catch (std::bad_alloc&) { + LERROR(fmt::format( + "Allocation error with script playback from keyframe entry {}", + lineN - 1 + )); + return; + } + catch (std::length_error&) { + LERROR(fmt::format( + "length_error with script playback from keyframe entry {}", + lineN - 1 + )); + return; + } + + if (!file) { + LERROR(fmt::format( + "Error reading script playback from keyframe entry {}", + lineN - 1 + )); + return; + } +} + +static void SessionRecording::readScriptKeyframeAscii(timestamps& times, + datamessagestructures::ScriptMessage& kf, + std::string filenameRead, + int lineN) +{ + std::string entryType; + std::istringstream iss(filenameRead); + iss >> entryType; + iss >> times.timeOs >> times.timeRec >> times.timeSim; + kf.read(&iss); + if (iss.fail()) { + LERROR(fmt::format( + "Error parsing script line {} of playback file", _playbackLineNum + )); + return; + } else if (!iss.eof()) { + LERROR(fmt::format( + "Did not find an EOL at line {} of playback file", _playbackLineNum + )); + return; } - double timeRef = appropriateTimestamp(timeOs, timeRec, timeSim); - addKeyframe(timeRef, pbFrame._script); } void SessionRecording::addKeyframe(double timestamp, From 915eefbf11c1d9aec00070c4f23d50ec04d16216 Mon Sep 17 00:00:00 2001 From: GPayne Date: Thu, 24 Oct 2019 13:06:52 -0600 Subject: [PATCH 09/64] Working on separating writing of recording keyframes into separate read & parse steps --- .../openspace/interaction/sessionrecording.h | 37 +++- src/interaction/sessionrecording.cpp | 179 +++++++++++------- 2 files changed, 137 insertions(+), 79 deletions(-) diff --git a/include/openspace/interaction/sessionrecording.h b/include/openspace/interaction/sessionrecording.h index 7cf6905312..69ddb74ee5 100644 --- a/include/openspace/interaction/sessionrecording.h +++ b/include/openspace/interaction/sessionrecording.h @@ -296,6 +296,29 @@ public: static void SessionRecording::readScriptKeyframeAscii(timestamps& times, datamessagestructures::ScriptMessage& kf, std::string filenameRead, int lineN); + /** + * Writes a camera keyframe to a binary format recording file using a CameraKeyframe + * + * \param times reference to a timestamps structure which contains recorded times + * \param kf reference to a camera keyframe which contains the camera details + * \param kfBuffer a buffer temporarily used for preparing data to be written + * \param idx index into the temporary buffer + * \param file an ofstream reference to the playback file being written-to + */ + static void SessionRecording::saveCameraKeyframeBinary(timestamps times, + datamessagestructures::CameraKeyframe& kf, unsigned char* kfBuffer, size_t& idx, + std::ofstream& file); + + /** + * Writes a camera keyframe to an ascii format recording file using a CameraKeyframe + * + * \param times reference to a timestamps structure which contains recorded times + * \param kf reference to a camera keyframe which contains the camera details + * \param file an ofstream reference to the playback file being written-to + */ + static void SessionRecording::saveCameraKeyframeAscii(timestamps times, + datamessagestructures::CameraKeyframe& kf, std::ofstream& file); + private: enum class RecordedType { Camera = 0, @@ -323,14 +346,11 @@ private: void playbackScript(); bool playbackAddEntriesToTimeline(); void signalPlaybackFinishedForComponent(RecordedType type); - void writeToFileBuffer(double src); - void writeToFileBuffer(std::vector& cvec); - void writeToFileBuffer(unsigned char c); - void writeToFileBuffer(bool b); void saveStringToFile(const std::string& s); - void saveKeyframeToFileBinary(unsigned char* bufferSource, size_t size); + void saveKeyframeToFileBinary(unsigned char* bufferSource, size_t size, + std::ofstream& file); void findFirstCameraKeyframeInTimeline(); - void saveKeyframeToFile(std::string entry); + void saveKeyframeToFile(std::string entry, std::ofstream& file); void addKeyframe(double timestamp, interaction::KeyframeNavigator::CameraPose keyframe); @@ -355,6 +375,11 @@ private: double getPrevTimestamp(); void cleanUpPlayback(); + static void writeToFileBuffer(unsigned char* buf, size_t& idx, double src); + static void writeToFileBuffer(unsigned char* buf, size_t& idx, std::vector& cv); + static void writeToFileBuffer(unsigned char* buf, size_t& idx, unsigned char c); + static void writeToFileBuffer(unsigned char* buf, size_t& idx, bool b); + RecordedDataMode _recordingDataMode = RecordedDataMode::Binary; SessionState _state = SessionState::Idle; SessionState _lastState = SessionState::Idle; diff --git a/src/interaction/sessionrecording.cpp b/src/interaction/sessionrecording.cpp index 656298d65a..89bde19f33 100644 --- a/src/interaction/sessionrecording.cpp +++ b/src/interaction/sessionrecording.cpp @@ -385,28 +385,40 @@ void SessionRecording::cleanUpPlayback() { _cleanupNeeded = false; } -void SessionRecording::writeToFileBuffer(double src) { +static void SessionRecording::writeToFileBuffer(unsigned char* buf, + size_t& idx, + double src) +{ const size_t writeSize_bytes = sizeof(double); unsigned char const *p = reinterpret_cast(&src); - memcpy((_keyframeBuffer + _bufferIndex), p, writeSize_bytes); - _bufferIndex += writeSize_bytes; + memcpy((buf + idx), p, writeSize_bytes); + idx += writeSize_bytes; } -void SessionRecording::writeToFileBuffer(std::vector& cvec) { - const size_t writeSize_bytes = cvec.size() * sizeof(char); - memcpy((_keyframeBuffer + _bufferIndex), cvec.data(), writeSize_bytes); - _bufferIndex += writeSize_bytes; +static void SessionRecording::writeToFileBuffer(unsigned char* buf, + size_t& idx, + std::vector& cv) +{ + const size_t writeSize_bytes = cv.size() * sizeof(char); + memcpy((buf + idx), cv.data(), writeSize_bytes); + idx += writeSize_bytes; } -void SessionRecording::writeToFileBuffer(unsigned char c) { +static void SessionRecording::writeToFileBuffer(unsigned char* buf, + size_t& idx, + unsigned char c) +{ const size_t writeSize_bytes = sizeof(char); - _keyframeBuffer[_bufferIndex] = c; - _bufferIndex += writeSize_bytes; + buf[idx] = c; + idx += writeSize_bytes; } -void SessionRecording::writeToFileBuffer(bool b) { - _keyframeBuffer[_bufferIndex] = b ? 1 : 0; - _bufferIndex += sizeof(char); +static void SessionRecording::writeToFileBuffer(unsigned char* buf, + size_t& idx, + bool b) +{ + buf[idx] = b ? 1 : 0; + idx += sizeof(char); } void SessionRecording::saveStringToFile(const std::string& s) { @@ -417,7 +429,7 @@ void SessionRecording::saveStringToFile(const std::string& s) { unsigned char const *p = reinterpret_cast(&strLen); memcpy((_keyframeBuffer + _bufferIndex), p, writeSize_bytes); _bufferIndex += static_cast(writeSize_bytes); - saveKeyframeToFileBinary(_keyframeBuffer, _bufferIndex); + saveKeyframeToFileBinary(_keyframeBuffer, _bufferIndex, _recordFile); _recordFile.write(s.c_str(), s.size()); } @@ -456,54 +468,71 @@ void SessionRecording::saveCameraKeyframe() { // & orientation of camera datamessagestructures::CameraKeyframe kf = _externInteract.generateCameraKeyframe(); + timestamps times = { + kf._timestamp, + kf._timestamp - _timestampRecordStarted, + global::timeManager.time().j2000Seconds() + }; if (_recordingDataMode == RecordedDataMode::Binary) { - // Writing to a binary session recording file - _bufferIndex = 0; - _keyframeBuffer[_bufferIndex++] = 'c'; - - // Writing to internal buffer, and then to file, for performance reasons - writeToFileBuffer(kf._timestamp); - writeToFileBuffer(kf._timestamp - _timestampRecordStarted); - writeToFileBuffer(global::timeManager.time().j2000Seconds()); - std::vector kfBuffer; - kf.serialize(kfBuffer); - writeToFileBuffer(kfBuffer); - - saveKeyframeToFileBinary(_keyframeBuffer, _bufferIndex); + saveCameraKeyframeBinary(times, kf, _keyframeBuffer, _bufferIndex, _recordFile); } else { - // Writing to an ASCII session recording file - std::stringstream keyframeLine = std::stringstream(); - // Add simulation timestamp, timestamp relative, simulation time to recording - // start - keyframeLine << "camera "; - keyframeLine << kf._timestamp << ' '; - keyframeLine << (kf._timestamp - _timestampRecordStarted) << ' '; - keyframeLine << std::fixed << std::setprecision(3) << - global::timeManager.time().j2000Seconds(); - keyframeLine << ' '; - // Add camera position - keyframeLine << std::fixed << std::setprecision(7) << kf._position.x << ' ' - << std::fixed << std::setprecision(7) << kf._position.y << ' ' - << std::fixed << std::setprecision(7) << kf._position.z << ' '; - // Add camera rotation - keyframeLine << std::fixed << std::setprecision(7) << kf._rotation.x << ' ' - << std::fixed << std::setprecision(7) << kf._rotation.y << ' ' - << std::fixed << std::setprecision(7) << kf._rotation.z << ' ' - << std::fixed << std::setprecision(7) << kf._rotation.w << ' '; - keyframeLine << std::scientific << kf._scale << ' '; - if (kf._followNodeRotation) { - keyframeLine << "F "; - } - else { - keyframeLine << "- "; - } - keyframeLine << kf._focusNode; - - saveKeyframeToFile(keyframeLine.str()); + saveCameraKeyframeAscii(times, kf, _recordFile); } } +static void SessionRecording::saveCameraKeyframeBinary(timestamps times, + datamessagestructures::CameraKeyframe& kf, + unsigned char* kfBuffer, + size_t& idx, + std::ofstream& file) +{ + // Writing to a binary session recording file + idx = 0; + kfBuffer[idx++] = 'c'; + + // Writing to internal buffer, and then to file, for performance reasons + writeToFileBuffer(kfBuffer, idx, times.timeOs); + writeToFileBuffer(kfBuffer, idx, times.timeRec); + writeToFileBuffer(kfBuffer, idx, times.timeSim); + std::vector writeBuffer; + kf.serialize(writeBuffer); + writeToFileBuffer(kfBuffer, idx, writeBuffer); + + saveKeyframeToFileBinary(kfBuffer, idx, file); +} + +static void SessionRecording::saveCameraKeyframeAscii(timestamps times, + datamessagestructures::CameraKeyframe& kf, + std::ofstream& file) +{ + std::stringstream keyframeLine = std::stringstream(); + // Add simulation timestamp, timestamp relative, simulation time to recording start + keyframeLine << "camera "; + keyframeLine << times.timeOs << ' '; + keyframeLine << times.timeRec << ' '; + keyframeLine << std::fixed << std::setprecision(3) << times.timeSim << ' '; + // Add camera position + keyframeLine << std::fixed << std::setprecision(7) << kf._position.x << ' ' + << std::fixed << std::setprecision(7) << kf._position.y << ' ' + << std::fixed << std::setprecision(7) << kf._position.z << ' '; + // Add camera rotation + keyframeLine << std::fixed << std::setprecision(7) << kf._rotation.x << ' ' + << std::fixed << std::setprecision(7) << kf._rotation.y << ' ' + << std::fixed << std::setprecision(7) << kf._rotation.z << ' ' + << std::fixed << std::setprecision(7) << kf._rotation.w << ' '; + keyframeLine << std::scientific << kf._scale << ' '; + if (kf._followNodeRotation) { + keyframeLine << "F "; + } + else { + keyframeLine << "- "; + } + keyframeLine << kf._focusNode; + + saveKeyframeToFile(keyframeLine.str(), file); +} + void SessionRecording::saveTimeKeyframe() { if (_state != SessionState::Recording) { return; @@ -515,14 +544,15 @@ void SessionRecording::saveTimeKeyframe() { if (_recordingDataMode == RecordedDataMode::Binary) { _bufferIndex = 0; _keyframeBuffer[_bufferIndex++] = 't'; - writeToFileBuffer(kf._timestamp); - writeToFileBuffer(kf._timestamp - _timestampRecordStarted); - writeToFileBuffer(kf._time); - writeToFileBuffer(kf._dt); - writeToFileBuffer(kf._paused); - writeToFileBuffer(kf._requiresTimeJump); + writeToFileBuffer(_keyframeBuffer, _bufferIndex, kf._timestamp); + writeToFileBuffer(_keyframeBuffer, _bufferIndex, kf._timestamp + - _timestampRecordStarted); + writeToFileBuffer(_keyframeBuffer, _bufferIndex, kf._time); + writeToFileBuffer(_keyframeBuffer, _bufferIndex, kf._dt); + writeToFileBuffer(_keyframeBuffer, _bufferIndex, kf._paused); + writeToFileBuffer(_keyframeBuffer, _bufferIndex, kf._requiresTimeJump); - saveKeyframeToFileBinary(_keyframeBuffer, _bufferIndex); + saveKeyframeToFileBinary(_keyframeBuffer, _bufferIndex, _recordFile); } else { std::stringstream keyframeLine = std::stringstream(); //Add simulation timestamp, timestamp relative, simulation time to recording start @@ -545,7 +575,7 @@ void SessionRecording::saveTimeKeyframe() { else { keyframeLine << " -"; } - saveKeyframeToFile(keyframeLine.str()); + saveKeyframeToFile(keyframeLine.str(), _recordFile); } } @@ -560,11 +590,11 @@ void SessionRecording::saveScriptKeyframe(std::string scriptToSave) { if (_recordingDataMode == RecordedDataMode::Binary) { _bufferIndex = 0; _keyframeBuffer[_bufferIndex++] = 's'; - writeToFileBuffer(sm._timestamp); - writeToFileBuffer(sm._timestamp - _timestampRecordStarted); - writeToFileBuffer(global::timeManager.time().j2000Seconds()); + writeToFileBuffer(_keyframeBuffer, _bufferIndex, sm._timestamp); + writeToFileBuffer(_keyframeBuffer, _bufferIndex, sm._timestamp - _timestampRecordStarted); + writeToFileBuffer(_keyframeBuffer, _bufferIndex, global::timeManager.time().j2000Seconds()); //Write header to file - saveKeyframeToFileBinary(_keyframeBuffer, _bufferIndex); + saveKeyframeToFileBinary(_keyframeBuffer, _bufferIndex, _recordFile); saveStringToFile(scriptToSave); } @@ -583,7 +613,7 @@ void SessionRecording::saveScriptKeyframe(std::string scriptToSave) { keyframeLine << (numLinesInScript + 1) << ' '; keyframeLine << scriptToSave; - saveKeyframeToFile(keyframeLine.str()); + saveKeyframeToFile(keyframeLine.str(), _recordFile); } } @@ -1320,12 +1350,15 @@ SessionRecording::RecordedType SessionRecording::getPrevKeyframeType() { } } -void SessionRecording::saveKeyframeToFileBinary(unsigned char* buffer, size_t size) { - _recordFile.write(reinterpret_cast(buffer), size); +void SessionRecording::saveKeyframeToFileBinary(unsigned char* buffer, + size_t size, + std::ofstream& file) +{ + file.write(reinterpret_cast(buffer), size); } -void SessionRecording::saveKeyframeToFile(std::string entry) { - _recordFile << std::move(entry) << std::endl; +void SessionRecording::saveKeyframeToFile(std::string entry, std::ofstream& file) { + file << std::move(entry) << std::endl; } SessionRecording::CallbackHandle SessionRecording::addStateChangeCallback( From ae5da23b0434d8b228dee72e3dc9b6a56cd3f435 Mon Sep 17 00:00:00 2001 From: GPayne Date: Mon, 28 Oct 2019 15:56:27 -0600 Subject: [PATCH 10/64] Separated writing of time keyframes into separate read & parse steps --- .../openspace/interaction/sessionrecording.h | 27 +++++- src/interaction/sessionrecording.cpp | 91 ++++++++++++------- 2 files changed, 81 insertions(+), 37 deletions(-) diff --git a/include/openspace/interaction/sessionrecording.h b/include/openspace/interaction/sessionrecording.h index 69ddb74ee5..a584dd56c6 100644 --- a/include/openspace/interaction/sessionrecording.h +++ b/include/openspace/interaction/sessionrecording.h @@ -303,7 +303,7 @@ public: * \param kf reference to a camera keyframe which contains the camera details * \param kfBuffer a buffer temporarily used for preparing data to be written * \param idx index into the temporary buffer - * \param file an ofstream reference to the playback file being written-to + * \param file an ofstream reference to the recording file being written-to */ static void SessionRecording::saveCameraKeyframeBinary(timestamps times, datamessagestructures::CameraKeyframe& kf, unsigned char* kfBuffer, size_t& idx, @@ -314,11 +314,34 @@ public: * * \param times reference to a timestamps structure which contains recorded times * \param kf reference to a camera keyframe which contains the camera details - * \param file an ofstream reference to the playback file being written-to + * \param file an ofstream reference to the recording file being written-to */ static void SessionRecording::saveCameraKeyframeAscii(timestamps times, datamessagestructures::CameraKeyframe& kf, std::ofstream& file); + /** + * Writes a time keyframe to a binary format recording file using a TimeKeyframe + * + * \param times reference to a timestamps structure which contains recorded times + * \param kf reference to a time keyframe which contains the time details + * \param kfBuffer a buffer temporarily used for preparing data to be written + * \param idx index into the temporary buffer + * \param file an ofstream reference to the recording file being written-to + */ + static void SessionRecording::saveTimeKeyframeBinary(timestamps times, + datamessagestructures::TimeKeyframe& kf, unsigned char* kfBuffer, size_t& idx, + std::ofstream& file); + + /** + * Writes a time keyframe to an ascii format recording file using a TimeKeyframe + * + * \param times reference to a timestamps structure which contains recorded times + * \param kf reference to a time keyframe which contains the time details + * \param file an ofstream reference to the recording file being written-to + */ + static void SessionRecording::saveTimeKeyframeAscii(timestamps times, + datamessagestructures::TimeKeyframe& kf, std::ofstream& file); + private: enum class RecordedType { Camera = 0, diff --git a/src/interaction/sessionrecording.cpp b/src/interaction/sessionrecording.cpp index 89bde19f33..7547c834a9 100644 --- a/src/interaction/sessionrecording.cpp +++ b/src/interaction/sessionrecording.cpp @@ -513,11 +513,13 @@ static void SessionRecording::saveCameraKeyframeAscii(timestamps times, keyframeLine << times.timeRec << ' '; keyframeLine << std::fixed << std::setprecision(3) << times.timeSim << ' '; // Add camera position - keyframeLine << std::fixed << std::setprecision(7) << kf._position.x << ' ' + keyframeLine + << std::fixed << std::setprecision(7) << kf._position.x << ' ' << std::fixed << std::setprecision(7) << kf._position.y << ' ' << std::fixed << std::setprecision(7) << kf._position.z << ' '; // Add camera rotation - keyframeLine << std::fixed << std::setprecision(7) << kf._rotation.x << ' ' + keyframeLine + << std::fixed << std::setprecision(7) << kf._rotation.x << ' ' << std::fixed << std::setprecision(7) << kf._rotation.y << ' ' << std::fixed << std::setprecision(7) << kf._rotation.z << ' ' << std::fixed << std::setprecision(7) << kf._rotation.w << ' '; @@ -541,44 +543,63 @@ void SessionRecording::saveTimeKeyframe() { //Create a time keyframe, then call to populate it with current time props datamessagestructures::TimeKeyframe kf = _externInteract.generateTimeKeyframe(); + timestamps times = { + kf._timestamp, + kf._timestamp - _timestampRecordStarted, + global::timeManager.time().j2000Seconds() + }; if (_recordingDataMode == RecordedDataMode::Binary) { - _bufferIndex = 0; - _keyframeBuffer[_bufferIndex++] = 't'; - writeToFileBuffer(_keyframeBuffer, _bufferIndex, kf._timestamp); - writeToFileBuffer(_keyframeBuffer, _bufferIndex, kf._timestamp - - _timestampRecordStarted); - writeToFileBuffer(_keyframeBuffer, _bufferIndex, kf._time); - writeToFileBuffer(_keyframeBuffer, _bufferIndex, kf._dt); - writeToFileBuffer(_keyframeBuffer, _bufferIndex, kf._paused); - writeToFileBuffer(_keyframeBuffer, _bufferIndex, kf._requiresTimeJump); - - saveKeyframeToFileBinary(_keyframeBuffer, _bufferIndex, _recordFile); + saveTimeKeyframeBinary(times, kf, _keyframeBuffer, _bufferIndex, _recordFile); } else { - std::stringstream keyframeLine = std::stringstream(); - //Add simulation timestamp, timestamp relative, simulation time to recording start - keyframeLine << "time "; - keyframeLine << kf._timestamp << ' '; - keyframeLine << (kf._timestamp - _timestampRecordStarted) << ' '; - - keyframeLine << std::fixed << std::setprecision(3) << kf._time; - - keyframeLine << ' ' << kf._dt; - if (kf._paused) { - keyframeLine << " P"; - } - else { - keyframeLine << " R"; - } - if (kf._requiresTimeJump) { - keyframeLine << " J"; - } - else { - keyframeLine << " -"; - } - saveKeyframeToFile(keyframeLine.str(), _recordFile); + saveTimeKeyframeAscii(times, kf, _recordFile); } } +static void SessionRecording::saveTimeKeyframeBinary(timestamps times, + datamessagestructures::TimeKeyframe& kf, + unsigned char* kfBuffer, + size_t& idx, + std::ofstream& file) +{ + idx = 0; + kfBuffer[idx++] = 't'; + writeToFileBuffer(kfBuffer, idx, times.timeOs); + writeToFileBuffer(kfBuffer, idx, times.timeRec); + writeToFileBuffer(kfBuffer, idx, times.timeSim); + std::vector writeBuffer; + kf.serialize(writeBuffer); + writeToFileBuffer(kfBuffer, idx, writeBuffer); + + saveKeyframeToFileBinary(kfBuffer, idx, file); +} + +static void SessionRecording::saveTimeKeyframeAscii(timestamps times, + datamessagestructures::CameraKeyframe& kf, + std::ofstream& file) +{ + std::stringstream keyframeLine = std::stringstream(); + //Add simulation timestamp, timestamp relative, simulation time to recording start + keyframeLine << "time "; + keyframeLine << times.timeOs << ' '; + keyframeLine << times.timeRec << ' '; + keyframeLine << std::fixed << std::setprecision(3) << times.timeSim << ' '; + + keyframeLine << ' ' << kf._dt; + if (kf._paused) { + keyframeLine << " P"; + } + else { + keyframeLine << " R"; + } + if (kf._requiresTimeJump) { + keyframeLine << " J"; + } + else { + keyframeLine << " -"; + } + saveKeyframeToFile(keyframeLine.str(), _recordFile); +} + void SessionRecording::saveScriptKeyframe(std::string scriptToSave) { if (_state != SessionState::Recording) { return; From 37924c273464acdb1f9b19da27e7cb5e037ec9d4 Mon Sep 17 00:00:00 2001 From: GPayne Date: Tue, 29 Oct 2019 19:23:34 -0600 Subject: [PATCH 11/64] Finished separating script messages into separate read & parse steps --- .../openspace/interaction/sessionrecording.h | 34 +++- include/openspace/network/messagestructures.h | 59 ++++++ src/interaction/sessionrecording.cpp | 172 ++++++++---------- 3 files changed, 166 insertions(+), 99 deletions(-) diff --git a/include/openspace/interaction/sessionrecording.h b/include/openspace/interaction/sessionrecording.h index a584dd56c6..a9dc5852c1 100644 --- a/include/openspace/interaction/sessionrecording.h +++ b/include/openspace/interaction/sessionrecording.h @@ -302,11 +302,10 @@ public: * \param times reference to a timestamps structure which contains recorded times * \param kf reference to a camera keyframe which contains the camera details * \param kfBuffer a buffer temporarily used for preparing data to be written - * \param idx index into the temporary buffer * \param file an ofstream reference to the recording file being written-to */ static void SessionRecording::saveCameraKeyframeBinary(timestamps times, - datamessagestructures::CameraKeyframe& kf, unsigned char* kfBuffer, size_t& idx, + datamessagestructures::CameraKeyframe& kf, unsigned char* kfBuffer, std::ofstream& file); /** @@ -325,11 +324,10 @@ public: * \param times reference to a timestamps structure which contains recorded times * \param kf reference to a time keyframe which contains the time details * \param kfBuffer a buffer temporarily used for preparing data to be written - * \param idx index into the temporary buffer * \param file an ofstream reference to the recording file being written-to */ static void SessionRecording::saveTimeKeyframeBinary(timestamps times, - datamessagestructures::TimeKeyframe& kf, unsigned char* kfBuffer, size_t& idx, + datamessagestructures::TimeKeyframe& kf, unsigned char* kfBuffer, std::ofstream& file); /** @@ -342,6 +340,28 @@ public: static void SessionRecording::saveTimeKeyframeAscii(timestamps times, datamessagestructures::TimeKeyframe& kf, std::ofstream& file); + /** + * Writes a script keyframe to a binary format recording file using a ScriptMessage + * + * \param times reference to a timestamps structure which contains recorded times + * \param sm reference to a ScriptMessage object which contains the script details + * \param smBuffer a buffer temporarily used for preparing data to be written + * \param file an ofstream reference to the recording file being written-to + */ + static void SessionRecording::saveScriptKeyframeBinary(timestamps times, + datamessagestructures::ScriptMessage& sm, unsigned char* smBuffer, + std::string& script, std::ofstream& file); + + /** + * Writes a script keyframe to an ascii format recording file using a ScriptMessage + * + * \param times reference to a timestamps structure which contains recorded times + * \param sm reference to a ScriptMessage which contains the script details + * \param file an ofstream reference to the recording file being written-to + */ + static void SessionRecording::saveScriptKeyframeAscii(timestamps times, + datamessagestructures::ScriptMessage& sm, std::ofstream& file); + private: enum class RecordedType { Camera = 0, @@ -403,6 +423,11 @@ private: static void writeToFileBuffer(unsigned char* buf, size_t& idx, unsigned char c); static void writeToFileBuffer(unsigned char* buf, size_t& idx, bool b); + static void SessionRecording::saveHeaderBinary(timestamps times, char type, + unsigned char* kfBuffer, size_t& idx); + static void SessionRecording::saveHeaderAscii(timestamps times, std::string& type, + std::stringstream& line); + RecordedDataMode _recordingDataMode = RecordedDataMode::Binary; SessionState _state = SessionState::Idle; SessionState _lastState = SessionState::Idle; @@ -430,7 +455,6 @@ private: + saveBufferCameraSize_min + saveBufferStringSize_max; unsigned char _keyframeBuffer[_saveBufferMaxSize_bytes]; - size_t _bufferIndex = 0; bool _cleanupNeeded = false; diff --git a/include/openspace/network/messagestructures.h b/include/openspace/network/messagestructures.h index 8b9d72cc64..d68b0b6ab3 100644 --- a/include/openspace/network/messagestructures.h +++ b/include/openspace/network/messagestructures.h @@ -188,6 +188,26 @@ struct CameraKeyframe { ); }; + void write(std::stringstream& out) const { + // Add camera position + out << std::fixed << std::setprecision(7) << _position.x << ' ' + << std::fixed << std::setprecision(7) << _position.y << ' ' + << std::fixed << std::setprecision(7) << _position.z << ' '; + // Add camera rotation + out << std::fixed << std::setprecision(7) << _rotation.x << ' ' + << std::fixed << std::setprecision(7) << _rotation.y << ' ' + << std::fixed << std::setprecision(7) << _rotation.z << ' ' + << std::fixed << std::setprecision(7) << _rotation.w << ' '; + out << std::scientific << _scale << ' '; + if (_followNodeRotation) { + out << "F "; + } + else { + out << "- "; + } + out << _focusNode; + }; + void read(std::istream* in) { // Read position in->read( @@ -284,6 +304,22 @@ struct TimeKeyframe { ); }; + void write(std::stringstream out) const { + out << ' ' << _dt; + if (_paused) { + out << " P"; + } + else { + out << " R"; + } + if (_requiresTimeJump) { + out << " J"; + } + else { + out << " -"; + } + }; + void read(std::istream* in) { in->read( reinterpret_cast(this), @@ -402,6 +438,29 @@ struct ScriptMessage { out->write(_script.c_str(), _script.size()); }; + void write(unsigned char* buf, size_t& idx, std::ofstream& file) const { + size_t strLen = _script.size(); + size_t writeSize_bytes = sizeof(size_t); + + unsigned char const *p = reinterpret_cast(&strLen); + memcpy((buf + idx), p, writeSize_bytes); + idx += static_cast(writeSize_bytes); + + memcpy((buf + idx), _script.c_str(), _script.size()); + idx += static_cast(strLen); + file.write(reinterpret_cast(buf), idx); + //Write directly to file because some scripts can be very long + file.write(_script.c_str(), _script.size()); + }; + + void write(std::stringstream& ss) const { + unsigned int numLinesInScript = static_cast( + std::count(_script.begin(), _script.end(), '\n') + ); + ss << ' ' << (numLinesInScript + 1) << ' '; + ss << _script; + } + void read(std::istream* in) { size_t strLen; //Read string length from file diff --git a/src/interaction/sessionrecording.cpp b/src/interaction/sessionrecording.cpp index 7547c834a9..93e54dc8f6 100644 --- a/src/interaction/sessionrecording.cpp +++ b/src/interaction/sessionrecording.cpp @@ -421,17 +421,21 @@ static void SessionRecording::writeToFileBuffer(unsigned char* buf, idx += sizeof(char); } -void SessionRecording::saveStringToFile(const std::string& s) { +void SessionRecording::saveStringToFile(const std::string& s, + unsigned char* kfBuffer, + size_t& idx, + std::ofstream& file) +{ size_t strLen = s.size(); size_t writeSize_bytes = sizeof(size_t); - _bufferIndex = 0; + idx = 0; unsigned char const *p = reinterpret_cast(&strLen); - memcpy((_keyframeBuffer + _bufferIndex), p, writeSize_bytes); - _bufferIndex += static_cast(writeSize_bytes); - saveKeyframeToFileBinary(_keyframeBuffer, _bufferIndex, _recordFile); + memcpy((kfBuffer + idx), p, writeSize_bytes); + idx += static_cast(writeSize_bytes); + saveKeyframeToFileBinary(kfBuffer, idx, file); - _recordFile.write(s.c_str(), s.size()); + file.write(s.c_str(), s.size()); } bool SessionRecording::hasCameraChangedFromPrev( @@ -474,31 +478,46 @@ void SessionRecording::saveCameraKeyframe() { global::timeManager.time().j2000Seconds() }; if (_recordingDataMode == RecordedDataMode::Binary) { - saveCameraKeyframeBinary(times, kf, _keyframeBuffer, _bufferIndex, _recordFile); + saveCameraKeyframeBinary(times, kf, _keyframeBuffer, _recordFile); } else { saveCameraKeyframeAscii(times, kf, _recordFile); } } -static void SessionRecording::saveCameraKeyframeBinary(timestamps times, - datamessagestructures::CameraKeyframe& kf, - unsigned char* kfBuffer, - size_t& idx, - std::ofstream& file) +static void SessionRecording::saveHeaderBinary(timestamps times, + char type, + unsigned char* kfBuffer, + size_t& idx) { - // Writing to a binary session recording file - idx = 0; - kfBuffer[idx++] = 'c'; - - // Writing to internal buffer, and then to file, for performance reasons + kfBuffer[idx++] = type; writeToFileBuffer(kfBuffer, idx, times.timeOs); writeToFileBuffer(kfBuffer, idx, times.timeRec); writeToFileBuffer(kfBuffer, idx, times.timeSim); +} + +static void SessionRecording::saveHeaderAscii(timestamps times, + std::string& type, + std::stringstream& line) +{ + line << type << ' '; + line << times.timeOs << ' '; + line << times.timeRec << ' '; + line << std::fixed << std::setprecision(3) << times.timeSim << ' '; +} + +static void SessionRecording::saveCameraKeyframeBinary(timestamps times, + datamessagestructures::CameraKeyframe& kf, + unsigned char* kfBuffer, + std::ofstream& file) +{ + // Writing to a binary session recording file + size_t idx = 0; + saveHeaderBinary(times, 'c', kfBuffer, idx); + // Writing to internal buffer, and then to file, for performance reasons std::vector writeBuffer; kf.serialize(writeBuffer); writeToFileBuffer(kfBuffer, idx, writeBuffer); - saveKeyframeToFileBinary(kfBuffer, idx, file); } @@ -507,31 +526,8 @@ static void SessionRecording::saveCameraKeyframeAscii(timestamps times, std::ofstream& file) { std::stringstream keyframeLine = std::stringstream(); - // Add simulation timestamp, timestamp relative, simulation time to recording start - keyframeLine << "camera "; - keyframeLine << times.timeOs << ' '; - keyframeLine << times.timeRec << ' '; - keyframeLine << std::fixed << std::setprecision(3) << times.timeSim << ' '; - // Add camera position - keyframeLine - << std::fixed << std::setprecision(7) << kf._position.x << ' ' - << std::fixed << std::setprecision(7) << kf._position.y << ' ' - << std::fixed << std::setprecision(7) << kf._position.z << ' '; - // Add camera rotation - keyframeLine - << std::fixed << std::setprecision(7) << kf._rotation.x << ' ' - << std::fixed << std::setprecision(7) << kf._rotation.y << ' ' - << std::fixed << std::setprecision(7) << kf._rotation.z << ' ' - << std::fixed << std::setprecision(7) << kf._rotation.w << ' '; - keyframeLine << std::scientific << kf._scale << ' '; - if (kf._followNodeRotation) { - keyframeLine << "F "; - } - else { - keyframeLine << "- "; - } - keyframeLine << kf._focusNode; - + saveHeaderAscii(times, "camera", keyframeLine); + kf.write(keyframeLine); saveKeyframeToFile(keyframeLine.str(), file); } @@ -549,7 +545,7 @@ void SessionRecording::saveTimeKeyframe() { global::timeManager.time().j2000Seconds() }; if (_recordingDataMode == RecordedDataMode::Binary) { - saveTimeKeyframeBinary(times, kf, _keyframeBuffer, _bufferIndex, _recordFile); + saveTimeKeyframeBinary(times, kf, _keyframeBuffer, _recordFile); } else { saveTimeKeyframeAscii(times, kf, _recordFile); } @@ -558,18 +554,13 @@ void SessionRecording::saveTimeKeyframe() { static void SessionRecording::saveTimeKeyframeBinary(timestamps times, datamessagestructures::TimeKeyframe& kf, unsigned char* kfBuffer, - size_t& idx, std::ofstream& file) { - idx = 0; - kfBuffer[idx++] = 't'; - writeToFileBuffer(kfBuffer, idx, times.timeOs); - writeToFileBuffer(kfBuffer, idx, times.timeRec); - writeToFileBuffer(kfBuffer, idx, times.timeSim); + size_t idx = 0; + saveHeaderBinary(times, 't', kfBuffer, idx); std::vector writeBuffer; kf.serialize(writeBuffer); writeToFileBuffer(kfBuffer, idx, writeBuffer); - saveKeyframeToFileBinary(kfBuffer, idx, file); } @@ -578,25 +569,8 @@ static void SessionRecording::saveTimeKeyframeAscii(timestamps times, std::ofstream& file) { std::stringstream keyframeLine = std::stringstream(); - //Add simulation timestamp, timestamp relative, simulation time to recording start - keyframeLine << "time "; - keyframeLine << times.timeOs << ' '; - keyframeLine << times.timeRec << ' '; - keyframeLine << std::fixed << std::setprecision(3) << times.timeSim << ' '; - - keyframeLine << ' ' << kf._dt; - if (kf._paused) { - keyframeLine << " P"; - } - else { - keyframeLine << " R"; - } - if (kf._requiresTimeJump) { - keyframeLine << " J"; - } - else { - keyframeLine << " -"; - } + saveHeaderAscii(times, "time", keyframeLine); + kf.write(keyframeLine); saveKeyframeToFile(keyframeLine.str(), _recordFile); } @@ -608,36 +582,46 @@ void SessionRecording::saveScriptKeyframe(std::string scriptToSave) { datamessagestructures::ScriptMessage sm = _externInteract.generateScriptMessage(scriptToSave); - if (_recordingDataMode == RecordedDataMode::Binary) { - _bufferIndex = 0; - _keyframeBuffer[_bufferIndex++] = 's'; - writeToFileBuffer(_keyframeBuffer, _bufferIndex, sm._timestamp); - writeToFileBuffer(_keyframeBuffer, _bufferIndex, sm._timestamp - _timestampRecordStarted); - writeToFileBuffer(_keyframeBuffer, _bufferIndex, global::timeManager.time().j2000Seconds()); - //Write header to file - saveKeyframeToFileBinary(_keyframeBuffer, _bufferIndex, _recordFile); + timestamps times = { + sm._timestamp, + sm._timestamp - _timestampRecordStarted, + global::timeManager.time().j2000Seconds() + }; - saveStringToFile(scriptToSave); + if (_recordingDataMode == RecordedDataMode::Binary) { + saveScriptKeyframeBinary(times, sm, _keyframeBuffer, scriptToSave, + _recordFile); } else { - unsigned int numLinesInScript = static_cast( - std::count(scriptToSave.begin(), scriptToSave.end(), '\n') - ); - std::stringstream keyframeLine = std::stringstream(); - //Add simulation timestamp, timestamp relative, simulation time to recording start - keyframeLine << "script "; - keyframeLine << sm._timestamp << ' '; - keyframeLine << (sm._timestamp - _timestampRecordStarted) << ' '; - keyframeLine << std::fixed << std::setprecision(3) << - global::timeManager.time().j2000Seconds(); - keyframeLine << ' '; - keyframeLine << (numLinesInScript + 1) << ' '; - keyframeLine << scriptToSave; - - saveKeyframeToFile(keyframeLine.str(), _recordFile); + saveScriptKeyframeAscii(times, sm, _recordFile); } } +static void SessionRecording::saveScriptKeyframeBinary(timestamps times, + datamessagestructures::ScriptMessage& sm, + unsigned char* smBuffer, + std::string& script, + std::ofstream& file) +{ + size_t idx = 0; + saveHeaderBinary(times, 's', smBuffer, idx); + //Write script header to file + saveKeyframeToFileBinary(smBuffer, idx, file); + //Write script data to file + sm.write(smBuffer, idx, file); +} + +static void SessionRecording::saveScriptKeyframeAscii(timestamps times, + datamessagestructures::ScriptMessage& sm, + std::ofstream& file) +{ + + std::stringstream keyframeLine = std::stringstream(); + saveHeaderAscii(times, "script", keyframeLine); + sm.write(keyframeLine); + saveKeyframeToFile(keyframeLine.str(), _recordFile); +} + void SessionRecording::preSynchronization() { if (_state == SessionState::Recording) { saveCameraKeyframe(); From 88135c1db00873440984c84c6bd83e3a5c92085d Mon Sep 17 00:00:00 2001 From: GPayne Date: Thu, 31 Oct 2019 14:48:26 -0600 Subject: [PATCH 12/64] Fixed compile issues, now needs testing --- .../openspace/interaction/keyframenavigator.h | 10 +- .../openspace/interaction/sessionrecording.h | 43 ++--- include/openspace/network/messagestructures.h | 15 +- src/interaction/sessionrecording.cpp | 178 ++++++++---------- 4 files changed, 119 insertions(+), 127 deletions(-) diff --git a/include/openspace/interaction/keyframenavigator.h b/include/openspace/interaction/keyframenavigator.h index 77783d6bd4..50fae1d9eb 100644 --- a/include/openspace/interaction/keyframenavigator.h +++ b/include/openspace/interaction/keyframenavigator.h @@ -55,13 +55,21 @@ public: float scale; bool followFocusNodeRotation; + CameraPose() { + position = {0., 0., 0.}; + rotation = {0., 0., 0., 0.}; + focusNode = ""; + scale = 1.0; + followFocusNodeRotation = false; + }; + CameraPose(const openspace::datamessagestructures::CameraKeyframe& kf) { position = kf._position; rotation = kf._rotation; focusNode = kf._focusNode; scale = kf._scale; followFocusNodeRotation = kf._followNodeRotation; - } + }; }; /** diff --git a/include/openspace/interaction/sessionrecording.h b/include/openspace/interaction/sessionrecording.h index a9dc5852c1..46441feead 100644 --- a/include/openspace/interaction/sessionrecording.h +++ b/include/openspace/interaction/sessionrecording.h @@ -52,12 +52,12 @@ public: }; const std::string FileHeaderTitle = "OpenSpace_record/playback"; - constexpr const size_t FileHeaderVersionLength = 5; - constexpr const char FileHeaderVersion[FileHeaderVersionLength] = { + static const size_t FileHeaderVersionLength = 5; + const char FileHeaderVersion[FileHeaderVersionLength] = { '0', '0', '.', '8', '5' }; - constexpr const char DataFormatAsciiTag = 'A'; - constexpr const char DataFormatBinaryTag = 'B'; + const char DataFormatAsciiTag = 'A'; + const char DataFormatBinaryTag = 'B'; using CallbackHandle = int; using StateChangeCallback = std::function; @@ -255,7 +255,7 @@ public: * \param file an ifstream reference to the playback file being read * \param lineN keyframe number in playback file where this keyframe resides */ - static void SessionRecording::readTimeKeyframeBinary(timestamps& times, + static void readTimeKeyframeBinary(timestamps& times, datamessagestructures::TimeKeyframe& kf, std::ifstream& file, int lineN); /** @@ -267,7 +267,7 @@ public: * \param filenameRead a string containing the playback filename * \param lineN line number in playback file where this keyframe resides */ - static void SessionRecording::readTimeKeyframeAscii(timestamps& times, + static void readTimeKeyframeAscii(timestamps& times, datamessagestructures::TimeKeyframe& kf, std::string filenameRead, int lineN); /** @@ -280,7 +280,7 @@ public: * \param file an ifstream reference to the playback file being read * \param lineN keyframe number in playback file where this keyframe resides */ - static void SessionRecording::readScriptKeyframeBinary(timestamps& times, + static void readScriptKeyframeBinary(timestamps& times, datamessagestructures::ScriptMessage& kf, std::ifstream& file, int lineN); /** @@ -293,7 +293,7 @@ public: * \param filenameRead a string containing the playback filename * \param lineN line number in playback file where this keyframe resides */ - static void SessionRecording::readScriptKeyframeAscii(timestamps& times, + static void readScriptKeyframeAscii(timestamps& times, datamessagestructures::ScriptMessage& kf, std::string filenameRead, int lineN); /** @@ -304,7 +304,7 @@ public: * \param kfBuffer a buffer temporarily used for preparing data to be written * \param file an ofstream reference to the recording file being written-to */ - static void SessionRecording::saveCameraKeyframeBinary(timestamps times, + static void saveCameraKeyframeBinary(timestamps times, datamessagestructures::CameraKeyframe& kf, unsigned char* kfBuffer, std::ofstream& file); @@ -315,7 +315,7 @@ public: * \param kf reference to a camera keyframe which contains the camera details * \param file an ofstream reference to the recording file being written-to */ - static void SessionRecording::saveCameraKeyframeAscii(timestamps times, + static void saveCameraKeyframeAscii(timestamps times, datamessagestructures::CameraKeyframe& kf, std::ofstream& file); /** @@ -326,7 +326,7 @@ public: * \param kfBuffer a buffer temporarily used for preparing data to be written * \param file an ofstream reference to the recording file being written-to */ - static void SessionRecording::saveTimeKeyframeBinary(timestamps times, + static void saveTimeKeyframeBinary(timestamps times, datamessagestructures::TimeKeyframe& kf, unsigned char* kfBuffer, std::ofstream& file); @@ -337,7 +337,7 @@ public: * \param kf reference to a time keyframe which contains the time details * \param file an ofstream reference to the recording file being written-to */ - static void SessionRecording::saveTimeKeyframeAscii(timestamps times, + static void saveTimeKeyframeAscii(timestamps times, datamessagestructures::TimeKeyframe& kf, std::ofstream& file); /** @@ -348,9 +348,9 @@ public: * \param smBuffer a buffer temporarily used for preparing data to be written * \param file an ofstream reference to the recording file being written-to */ - static void SessionRecording::saveScriptKeyframeBinary(timestamps times, + static void saveScriptKeyframeBinary(timestamps times, datamessagestructures::ScriptMessage& sm, unsigned char* smBuffer, - std::string& script, std::ofstream& file); + std::ofstream& file); /** * Writes a script keyframe to an ascii format recording file using a ScriptMessage @@ -359,7 +359,7 @@ public: * \param sm reference to a ScriptMessage which contains the script details * \param file an ofstream reference to the recording file being written-to */ - static void SessionRecording::saveScriptKeyframeAscii(timestamps times, + static void saveScriptKeyframeAscii(timestamps times, datamessagestructures::ScriptMessage& sm, std::ofstream& file); private: @@ -389,11 +389,12 @@ private: void playbackScript(); bool playbackAddEntriesToTimeline(); void signalPlaybackFinishedForComponent(RecordedType type); - void saveStringToFile(const std::string& s); - void saveKeyframeToFileBinary(unsigned char* bufferSource, size_t size, - std::ofstream& file); void findFirstCameraKeyframeInTimeline(); - void saveKeyframeToFile(std::string entry, std::ofstream& file); + static void saveStringToFile(const std::string& s, unsigned char* kfBuffer, size_t& idx, + std::ofstream& file); + static void saveKeyframeToFileBinary(unsigned char* bufferSource, size_t size, + std::ofstream& file); + static void saveKeyframeToFile(std::string entry, std::ofstream& file); void addKeyframe(double timestamp, interaction::KeyframeNavigator::CameraPose keyframe); @@ -423,9 +424,9 @@ private: static void writeToFileBuffer(unsigned char* buf, size_t& idx, unsigned char c); static void writeToFileBuffer(unsigned char* buf, size_t& idx, bool b); - static void SessionRecording::saveHeaderBinary(timestamps times, char type, + static void saveHeaderBinary(timestamps times, char type, unsigned char* kfBuffer, size_t& idx); - static void SessionRecording::saveHeaderAscii(timestamps times, std::string& type, + static void saveHeaderAscii(timestamps times, const std::string& type, std::stringstream& line); RecordedDataMode _recordingDataMode = RecordedDataMode::Binary; diff --git a/include/openspace/network/messagestructures.h b/include/openspace/network/messagestructures.h index d68b0b6ab3..4f1bf0c4a8 100644 --- a/include/openspace/network/messagestructures.h +++ b/include/openspace/network/messagestructures.h @@ -30,6 +30,8 @@ #include #include #include +#include +#include namespace openspace::datamessagestructures { @@ -254,7 +256,7 @@ struct CameraKeyframe { ); }; - void read(std::istringstream* iss) { + void read(std::istringstream& iss) { std::string rotationFollowing; iss >> _position.x @@ -304,7 +306,7 @@ struct TimeKeyframe { ); }; - void write(std::stringstream out) const { + void write(std::stringstream& out) const { out << ' ' << _dt; if (_paused) { out << " P"; @@ -327,7 +329,7 @@ struct TimeKeyframe { ); }; - void read(std::istringstream* iss) { + void read(std::istringstream& iss) { std::string paused, jump; iss >> _dt @@ -474,12 +476,15 @@ struct ScriptMessage { _script = temp.data(); }; - void read(std::istringstream* iss) { + void read(std::istringstream& iss) { int numScriptLines; iss >> numScriptLines; + if (numScriptLines < 0) { + numScriptLines = 0; + } std::string tmpReadbackScript; _script.erase(); - for (unsigned int i = 0; i < numScriptLines; ++i) { + for (int i = 0; i < numScriptLines; ++i) { std::getline(iss, tmpReadbackScript); _script.append(tmpReadbackScript); if (i < (numScriptLines - 1)) { diff --git a/src/interaction/sessionrecording.cpp b/src/interaction/sessionrecording.cpp index 93e54dc8f6..96b437a00f 100644 --- a/src/interaction/sessionrecording.cpp +++ b/src/interaction/sessionrecording.cpp @@ -54,30 +54,6 @@ namespace { return res; } - template <> - bool readFromPlayback(std::ifstream& stream) { - unsigned char b; - stream.read(reinterpret_cast(&b), sizeof(unsigned char)); - if (b == 0) { - return false; - } - else { - return true; - } - } - - template <> - std::string readFromPlayback(std::ifstream& stream) { - size_t strLen; - // Read string length from file - stream.read(reinterpret_cast(&strLen), sizeof(strLen)); - // Read back full string - std::vector temp(strLen + 1); - stream.read(temp.data(), strLen); - temp[strLen] = '\0'; - return temp.data(); - } - std::string readHeaderElement(std::ifstream& stream, size_t readLen_chars) { std::vector readTemp(readLen_chars); stream.read(&readTemp[0], readLen_chars); @@ -183,7 +159,8 @@ void SessionRecording::stopRecording() { } bool SessionRecording::startPlayback(const std::string& filename, - KeyframeTimeRef timeMode, bool forceSimTimeAtStart) + KeyframeTimeRef timeMode, + bool forceSimTimeAtStart) { if (filename.find("/") != std::string::npos) { LERROR("Playback filename must not contain path (/) elements"); @@ -385,9 +362,9 @@ void SessionRecording::cleanUpPlayback() { _cleanupNeeded = false; } -static void SessionRecording::writeToFileBuffer(unsigned char* buf, - size_t& idx, - double src) +void SessionRecording::writeToFileBuffer(unsigned char* buf, + size_t& idx, + double src) { const size_t writeSize_bytes = sizeof(double); unsigned char const *p = reinterpret_cast(&src); @@ -395,27 +372,27 @@ static void SessionRecording::writeToFileBuffer(unsigned char* buf, idx += writeSize_bytes; } -static void SessionRecording::writeToFileBuffer(unsigned char* buf, - size_t& idx, - std::vector& cv) +void SessionRecording::writeToFileBuffer(unsigned char* buf, + size_t& idx, + std::vector& cv) { const size_t writeSize_bytes = cv.size() * sizeof(char); memcpy((buf + idx), cv.data(), writeSize_bytes); idx += writeSize_bytes; } -static void SessionRecording::writeToFileBuffer(unsigned char* buf, - size_t& idx, - unsigned char c) +void SessionRecording::writeToFileBuffer(unsigned char* buf, + size_t& idx, + unsigned char c) { const size_t writeSize_bytes = sizeof(char); buf[idx] = c; idx += writeSize_bytes; } -static void SessionRecording::writeToFileBuffer(unsigned char* buf, - size_t& idx, - bool b) +void SessionRecording::writeToFileBuffer(unsigned char* buf, + size_t& idx, + bool b) { buf[idx] = b ? 1 : 0; idx += sizeof(char); @@ -439,7 +416,7 @@ void SessionRecording::saveStringToFile(const std::string& s, } bool SessionRecording::hasCameraChangedFromPrev( - datamessagestructures::CameraKeyframe kfNew) + datamessagestructures::CameraKeyframe kfNew) { constexpr const double threshold = 1e-2; bool hasChanged = false; @@ -485,10 +462,10 @@ void SessionRecording::saveCameraKeyframe() { } } -static void SessionRecording::saveHeaderBinary(timestamps times, - char type, - unsigned char* kfBuffer, - size_t& idx) +void SessionRecording::saveHeaderBinary(timestamps times, + char type, + unsigned char* kfBuffer, + size_t& idx) { kfBuffer[idx++] = type; writeToFileBuffer(kfBuffer, idx, times.timeOs); @@ -496,9 +473,9 @@ static void SessionRecording::saveHeaderBinary(timestamps times, writeToFileBuffer(kfBuffer, idx, times.timeSim); } -static void SessionRecording::saveHeaderAscii(timestamps times, - std::string& type, - std::stringstream& line) +void SessionRecording::saveHeaderAscii(timestamps times, + const std::string& type, + std::stringstream& line) { line << type << ' '; line << times.timeOs << ' '; @@ -506,10 +483,10 @@ static void SessionRecording::saveHeaderAscii(timestamps times, line << std::fixed << std::setprecision(3) << times.timeSim << ' '; } -static void SessionRecording::saveCameraKeyframeBinary(timestamps times, - datamessagestructures::CameraKeyframe& kf, - unsigned char* kfBuffer, - std::ofstream& file) +void SessionRecording::saveCameraKeyframeBinary(timestamps times, + datamessagestructures::CameraKeyframe& kf, + unsigned char* kfBuffer, + std::ofstream& file) { // Writing to a binary session recording file size_t idx = 0; @@ -521,9 +498,9 @@ static void SessionRecording::saveCameraKeyframeBinary(timestamps times, saveKeyframeToFileBinary(kfBuffer, idx, file); } -static void SessionRecording::saveCameraKeyframeAscii(timestamps times, +void SessionRecording::saveCameraKeyframeAscii(timestamps times, datamessagestructures::CameraKeyframe& kf, - std::ofstream& file) + std::ofstream& file) { std::stringstream keyframeLine = std::stringstream(); saveHeaderAscii(times, "camera", keyframeLine); @@ -551,10 +528,10 @@ void SessionRecording::saveTimeKeyframe() { } } -static void SessionRecording::saveTimeKeyframeBinary(timestamps times, - datamessagestructures::TimeKeyframe& kf, - unsigned char* kfBuffer, - std::ofstream& file) +void SessionRecording::saveTimeKeyframeBinary(timestamps times, + datamessagestructures::TimeKeyframe& kf, + unsigned char* kfBuffer, + std::ofstream& file) { size_t idx = 0; saveHeaderBinary(times, 't', kfBuffer, idx); @@ -564,14 +541,14 @@ static void SessionRecording::saveTimeKeyframeBinary(timestamps times, saveKeyframeToFileBinary(kfBuffer, idx, file); } -static void SessionRecording::saveTimeKeyframeAscii(timestamps times, - datamessagestructures::CameraKeyframe& kf, - std::ofstream& file) +void SessionRecording::saveTimeKeyframeAscii(timestamps times, + datamessagestructures::TimeKeyframe& kf, + std::ofstream& file) { std::stringstream keyframeLine = std::stringstream(); saveHeaderAscii(times, "time", keyframeLine); kf.write(keyframeLine); - saveKeyframeToFile(keyframeLine.str(), _recordFile); + saveKeyframeToFile(keyframeLine.str(), file); } void SessionRecording::saveScriptKeyframe(std::string scriptToSave) { @@ -589,19 +566,17 @@ void SessionRecording::saveScriptKeyframe(std::string scriptToSave) { }; if (_recordingDataMode == RecordedDataMode::Binary) { - saveScriptKeyframeBinary(times, sm, _keyframeBuffer, scriptToSave, - _recordFile); + saveScriptKeyframeBinary(times, sm, _keyframeBuffer, _recordFile); } else { saveScriptKeyframeAscii(times, sm, _recordFile); } } -static void SessionRecording::saveScriptKeyframeBinary(timestamps times, - datamessagestructures::ScriptMessage& sm, - unsigned char* smBuffer, - std::string& script, - std::ofstream& file) +void SessionRecording::saveScriptKeyframeBinary(timestamps times, + datamessagestructures::ScriptMessage& sm, + unsigned char* smBuffer, + std::ofstream& file) { size_t idx = 0; saveHeaderBinary(times, 's', smBuffer, idx); @@ -611,15 +586,15 @@ static void SessionRecording::saveScriptKeyframeBinary(timestamps times, sm.write(smBuffer, idx, file); } -static void SessionRecording::saveScriptKeyframeAscii(timestamps times, - datamessagestructures::ScriptMessage& sm, - std::ofstream& file) +void SessionRecording::saveScriptKeyframeAscii(timestamps times, + datamessagestructures::ScriptMessage& sm, + std::ofstream& file) { std::stringstream keyframeLine = std::stringstream(); saveHeaderAscii(times, "script", keyframeLine); sm.write(keyframeLine); - saveKeyframeToFile(keyframeLine.str(), _recordFile); + saveKeyframeToFile(keyframeLine.str(), file); } void SessionRecording::preSynchronization() { @@ -743,7 +718,8 @@ bool SessionRecording::playbackAddEntriesToTimeline() { return !parsingErrorsFound; } -double SessionRecording::appropriateTimestamp(double timeOs, double timeRec, +double SessionRecording::appropriateTimestamp(double timeOs, + double timeRec, double timeSim) { if (_playbackTimeReferenceMode == KeyframeTimeRef::Relative_recordedStart) { @@ -757,7 +733,8 @@ double SessionRecording::appropriateTimestamp(double timeOs, double timeRec, } } -double SessionRecording::equivalentSimulationTime(double timeOs, double timeRec, +double SessionRecording::equivalentSimulationTime(double timeOs, + double timeRec, double timeSim) { if (_playbackTimeReferenceMode == KeyframeTimeRef::Relative_recordedStart) { @@ -771,7 +748,8 @@ double SessionRecording::equivalentSimulationTime(double timeOs, double timeRec, } } -double SessionRecording::equivalentApplicationTime(double timeOs, double timeRec, +double SessionRecording::equivalentApplicationTime(double timeOs, + double timeRec, double timeSim) { if (_playbackTimeReferenceMode == KeyframeTimeRef::Relative_recordedStart) { @@ -837,9 +815,9 @@ void SessionRecording::playbackCamera() { addKeyframe(timeRef, pbFrame); } -static void SessionRecording::readCameraKeyframeBinary(timestamps& times, - datamessagestructures::CameraKeyframe& kf, - std::ifstream& file, int lineN) +void SessionRecording::readCameraKeyframeBinary(timestamps& times, + datamessagestructures::CameraKeyframe& kf, + std::ifstream& file, int lineN) { times.timeOs = readFromPlayback(file); times.timeRec = readFromPlayback(file); @@ -872,10 +850,10 @@ static void SessionRecording::readCameraKeyframeBinary(timestamps& times, } } -static void SessionRecording::readCameraKeyframeAscii(timestamps& times, - datamessagestructures::CameraKeyframe& kf, - std::string filenameRead, - int lineN) +void SessionRecording::readCameraKeyframeAscii(timestamps& times, + datamessagestructures::CameraKeyframe& kf, + std::string filenameRead, + int lineN) { std::string rotationFollowing; std::string entryType; @@ -883,7 +861,7 @@ static void SessionRecording::readCameraKeyframeAscii(timestamps& times, std::istringstream iss(filenameRead); iss >> entryType; iss >> times.timeOs >> times.timeRec >> times.timeSim; - kf.read(&iss); + kf.read(iss); if (iss.fail() || !iss.eof()) { LERROR(fmt::format("Error parsing camera line {} of playback file", lineN)); @@ -908,9 +886,9 @@ void SessionRecording::playbackTimeChange() { addKeyframe(kf._timestamp, kf); } -static void SessionRecording::readTimeKeyframeBinary(timestamps& times, - datamessagestructures::TimeKeyframe& kf, - std::ifstream& file, int lineN) +void SessionRecording::readTimeKeyframeBinary(timestamps& times, + datamessagestructures::TimeKeyframe& kf, + std::ifstream& file, int lineN) { times.timeOs = readFromPlayback(file); times.timeRec = readFromPlayback(file); @@ -942,21 +920,21 @@ static void SessionRecording::readTimeKeyframeBinary(timestamps& times, } } -static void SessionRecording::readTimeKeyframeAscii(timestamps& times, - datamessagestructures::TimeKeyframe& kf, - std::string filenameRead, - int lineN) +void SessionRecording::readTimeKeyframeAscii(timestamps& times, + datamessagestructures::TimeKeyframe& kf, + std::string filenameRead, + int lineN) { std::string entryType; std::istringstream iss(filenameRead); iss >> entryType; iss >> times.timeOs >> times.timeRec >> times.timeSim; - kf.read(&iss); + kf.read(iss); if (iss.fail() || !iss.eof()) { LERROR(fmt::format( - "Error parsing time line {} of playback file", _playbackLineNum + "Error parsing time line {} of playback file", lineN )); return; } @@ -976,9 +954,9 @@ void SessionRecording::playbackScript() { addKeyframe(timeRef, kf._script); } -static void SessionRecording::readScriptKeyframeBinary(timestamps& times, - datamessagestructures::ScriptMessage& kf, - std::ifstream& file, int lineN) +void SessionRecording::readScriptKeyframeBinary(timestamps& times, + datamessagestructures::ScriptMessage& kf, + std::ifstream& file, int lineN) { times.timeOs = readFromPlayback(file); times.timeRec = readFromPlayback(file); @@ -1011,24 +989,24 @@ static void SessionRecording::readScriptKeyframeBinary(timestamps& times, } } -static void SessionRecording::readScriptKeyframeAscii(timestamps& times, - datamessagestructures::ScriptMessage& kf, - std::string filenameRead, - int lineN) +void SessionRecording::readScriptKeyframeAscii(timestamps& times, + datamessagestructures::ScriptMessage& kf, + std::string filenameRead, + int lineN) { std::string entryType; std::istringstream iss(filenameRead); iss >> entryType; iss >> times.timeOs >> times.timeRec >> times.timeSim; - kf.read(&iss); + kf.read(iss); if (iss.fail()) { LERROR(fmt::format( - "Error parsing script line {} of playback file", _playbackLineNum + "Error parsing script line {} of playback file", lineN )); return; } else if (!iss.eof()) { LERROR(fmt::format( - "Did not find an EOL at line {} of playback file", _playbackLineNum + "Did not find an EOL at line {} of playback file", lineN )); return; } From 97e393b0f6b78c103f258cc0ed848db6f8ac6eea Mon Sep 17 00:00:00 2001 From: GPayne Date: Thu, 27 Feb 2020 13:35:10 -0700 Subject: [PATCH 13/64] Added task code for conversion to ascii --- .../openspace/interaction/sessionrecording.h | 9 +++ .../interaction/sessionrecording.inl | 7 ++ .../interaction/tasks/convertrecformattask.h | 13 ++- src/interaction/sessionrecording.cpp | 20 ++--- .../tasks/convertrecformattask.cpp | 80 +++++++++++++++---- 5 files changed, 99 insertions(+), 30 deletions(-) diff --git a/include/openspace/interaction/sessionrecording.h b/include/openspace/interaction/sessionrecording.h index 46441feead..3b3372ba56 100644 --- a/include/openspace/interaction/sessionrecording.h +++ b/include/openspace/interaction/sessionrecording.h @@ -362,6 +362,15 @@ public: static void saveScriptKeyframeAscii(timestamps times, datamessagestructures::ScriptMessage& sm, std::ofstream& file); + /** + * Reads header information from a session recording file + * + * \param stream reference to ifstream that contains the session recording file data + * \param readLen_chars number of characters to be read, which may be the expected + * length of the header line, or an arbitrary number of characters within it + */ + static std::string readHeaderElement(std::ifstream& stream, size_t readLen_chars); + private: enum class RecordedType { Camera = 0, diff --git a/include/openspace/interaction/sessionrecording.inl b/include/openspace/interaction/sessionrecording.inl index 0839562306..30876e95f8 100644 --- a/include/openspace/interaction/sessionrecording.inl +++ b/include/openspace/interaction/sessionrecording.inl @@ -51,4 +51,11 @@ T prevKeyframeObj(unsigned int index, const std::vector& keyframeContainer) { } } +template +T readFromPlayback(std::ifstream& stream) { + T res; + stream.read(reinterpret_cast(&res), sizeof(T)); + return res; +} + } // namespace openspace::interaction diff --git a/include/openspace/interaction/tasks/convertrecformattask.h b/include/openspace/interaction/tasks/convertrecformattask.h index 65c6aeef28..fab8dfab51 100644 --- a/include/openspace/interaction/tasks/convertrecformattask.h +++ b/include/openspace/interaction/tasks/convertrecformattask.h @@ -26,6 +26,7 @@ #define __OPENSPACE_CORE___CONVERTRECFORMATTASK___H__ #include +#include #include @@ -38,7 +39,7 @@ namespace { constexpr const char* KeyOutFilePath = "OutputFilePath"; } -namespace openspace { +namespace openspace::interaction { class ConvertRecFormatTask : public Task { public: @@ -51,19 +52,23 @@ public: std::string description() override; void perform(const Task::ProgressCallback& progressCallback) override; static documentation::Documentation documentation(); + void convert(); + SessionRecording::RecordedDataMode ConvertRecFormatTask::formatType(); private: void convertToAscii(); void convertToBinary(); - + std::string addFileSuffix(const std::string& filePath, const std::string& suffix); std::string _inFilePath; std::string _outFilePath; std::ifstream _iFile; - std::ifstream _oFile; + std::ofstream _oFile; std::string _valueFunctionLua; + + SessionRecording sr; }; -} // namespace openspace +} // namespace openspace::interaction #endif //__OPENSPACE_CORE___CONVERTRECFORMATTASK___H__ diff --git a/src/interaction/sessionrecording.cpp b/src/interaction/sessionrecording.cpp index 96b437a00f..c425d76b74 100644 --- a/src/interaction/sessionrecording.cpp +++ b/src/interaction/sessionrecording.cpp @@ -47,18 +47,6 @@ namespace { constexpr const bool UsingTimeKeyframes = false; - template - T readFromPlayback(std::ifstream& stream) { - T res; - stream.read(reinterpret_cast(&res), sizeof(T)); - return res; - } - - std::string readHeaderElement(std::ifstream& stream, size_t readLen_chars) { - std::vector readTemp(readLen_chars); - stream.read(&readTemp[0], readLen_chars); - return std::string(readTemp.begin(), readTemp.end()); - } } // namespace @@ -940,6 +928,14 @@ void SessionRecording::readTimeKeyframeAscii(timestamps& times, } } +static std::string SessionRecording::readHeaderElement(std::ifstream& stream, + size_t readLen_chars) +{ + std::vector readTemp(readLen_chars); + stream.read(&readTemp[0], readLen_chars); + return std::string(readTemp.begin(), readTemp.end()); +} + void SessionRecording::playbackScript() { timestamps times; datamessagestructures::ScriptMessage kf; diff --git a/src/interaction/tasks/convertrecformattask.cpp b/src/interaction/tasks/convertrecformattask.cpp index 1425e04e51..fbed41dd71 100644 --- a/src/interaction/tasks/convertrecformattask.cpp +++ b/src/interaction/tasks/convertrecformattask.cpp @@ -36,7 +36,7 @@ namespace { constexpr const char* _loggerCat = "ConvertRecFormatTask"; } // namespace -namespace openspace { +namespace openspace::interaction { ConvertRecFormatTask::ConvertRecFormatTask(const ghoul::Dictionary& dictionary) { openspace::documentation::testSpecificationAndThrow( @@ -68,12 +68,12 @@ void ConvertRecFormatTask::perform(const Task::ProgressCallback& progressCallbac } void ConvertRecFormatTask::convert() { - interaction::RecordedDataMode type = formatType(); + SessionRecording::RecordedDataMode type = formatType(); - if (type == interaction::RecordedDataMode::Ascii) { + if (type == SessionRecording::RecordedDataMode::Ascii) { convertToBinary(); } - else if (type == interaction::RecordedDataMode::Binary) { + else if (type == SessionRecording::RecordedDataMode::Binary) { convertToAscii(); } else { @@ -82,33 +82,83 @@ void ConvertRecFormatTask::convert() { } } -RecordedDataMode ConvertRecFormatTask::formatType() { +SessionRecording::RecordedDataMode ConvertRecFormatTask::formatType() { const std::string expectedHeader = "OpenSpace_record/playback"; std::string line; //Get first line, which is ASCII regardless of format std::getline(_iFile, line); - if (line.substr(0, interaction::FileHeaderTitle.length()) - != interaction::FileHeaderTitle) + if (line.substr(0, SessionRecording::FileHeaderTitle.length()) + != SessionRecording::FileHeaderTitle) { LERROR(fmt::format("Session recording file {} does not have expected header.", _inFilePath)); - return RecordedDataMode::Binary + 1; + return SessionRecording::RecordedDataMode::Binary + 1; } else { - if (line.back() == DataFormatAsciiTag) { - return RecordedDataMode::Ascii; + if (line.back() == SessionRecording::DataFormatAsciiTag) { + return SessionRecording::RecordedDataMode::Ascii; } - else if (line.back() == DataFormatBinaryTag) { - return RecordedDataMode::Binary; + else if (line.back() == SessionRecording::DataFormatBinaryTag) { + return SessionRecording::RecordedDataMode::Binary; } else { - return RecordedDataMode::Binary + 1; + return SessionRecording::RecordedDataMode::Binary + 1; } } } void ConvertRecFormatTask::convertToAscii() { + SessionRecording::timestamps times; + datamessagestructures::CameraKeyframe ckf; + datamessagestructures::TimeKeyframe tkf; + datamessagestructures::ScriptMessage skf; + int lineNum = 1; + unsigned char frameType; _outFilePath = addFileSuffix(_inFilePath, "_ascii"); + + bool fileReadOk = true; + while (fileReadOk) { + frameType = readFromPlayback(_iFile); + // Check if have reached EOF + if (!_iFile) { + LINFO(fmt::format( + "Finished converting {} entries from playback file {}", + lineNum - 1, _inFilePath + )); + fileReadOk = false; + break; + } + + if (frameType == 'c') { + SessionRecording::readCameraKeyframeBinary(times, ckf, _iFile, lineNum); + std::stringstream keyframeLine = std::stringstream(); + SessionRecording::saveHeaderAscii(times, "camera", keyframeLine); + ckf.write(keyframeLine); + SessionRecording::saveKeyframeToFile(keyframeLine.str(), _oFile); + } + else if (frameType == 't') { + SessionRecording::readTimeKeyframeBinary(times, tkf, _iFile, lineNum); + std::stringstream keyframeLine = std::stringstream(); + SessionRecording::saveHeaderAscii(times, "time", keyframeLine); + ckf.write(keyframeLine); + SessionRecording::saveKeyframeToFile(keyframeLine.str(), _oFile); + } + else if (frameType == 's') { + SessionRecording::readScriptKeyframeBinary(times, skf, _iFile, lineNum); + std::stringstream keyframeLine = std::stringstream(); + SessionRecording::saveHeaderAscii(times, "script", keyframeLine); + ckf.write(keyframeLine); + SessionRecording::saveKeyframeToFile(keyframeLine.str(), _oFile); + } + else { + LERROR(fmt::format( + "Unknown frame type @ index {} of playback file {}", + lineNum - 1, _inFilePath + )); + break; + } + lineNum++; + } } void ConvertRecFormatTask::convertToBinary() { @@ -118,7 +168,7 @@ void ConvertRecFormatTask::convertToBinary() { std::string ConvertRecFormatTask::addFileSuffix(const std::string& filePath, const std::string& suffix) { - size_t lastdot = filename.find_last_of("."); + size_t lastdot = filePath.find_last_of("."); std::string extension = filePath.substr(0, lastdot); if (lastdot == std::string::npos) { return filePath + suffix; @@ -155,3 +205,5 @@ documentation::Documentation ConvertRecFormatTask::documentation() { }, }; } + +} From 754dfd9c91864a009d1aa2885484f66a10f69f53 Mon Sep 17 00:00:00 2001 From: GPayne Date: Thu, 27 Feb 2020 13:45:30 -0700 Subject: [PATCH 14/64] Corrections to ascii conversion steps --- src/interaction/tasks/convertrecformattask.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/interaction/tasks/convertrecformattask.cpp b/src/interaction/tasks/convertrecformattask.cpp index fbed41dd71..d54c64f09e 100644 --- a/src/interaction/tasks/convertrecformattask.cpp +++ b/src/interaction/tasks/convertrecformattask.cpp @@ -115,6 +115,7 @@ void ConvertRecFormatTask::convertToAscii() { int lineNum = 1; unsigned char frameType; _outFilePath = addFileSuffix(_inFilePath, "_ascii"); + std::stringstream keyframeLine = std::stringstream(); bool fileReadOk = true; while (fileReadOk) { @@ -129,26 +130,21 @@ void ConvertRecFormatTask::convertToAscii() { break; } + keyframeLine.str(std::string()); if (frameType == 'c') { SessionRecording::readCameraKeyframeBinary(times, ckf, _iFile, lineNum); - std::stringstream keyframeLine = std::stringstream(); SessionRecording::saveHeaderAscii(times, "camera", keyframeLine); ckf.write(keyframeLine); - SessionRecording::saveKeyframeToFile(keyframeLine.str(), _oFile); } else if (frameType == 't') { SessionRecording::readTimeKeyframeBinary(times, tkf, _iFile, lineNum); - std::stringstream keyframeLine = std::stringstream(); SessionRecording::saveHeaderAscii(times, "time", keyframeLine); - ckf.write(keyframeLine); - SessionRecording::saveKeyframeToFile(keyframeLine.str(), _oFile); + tkf.write(keyframeLine); } else if (frameType == 's') { SessionRecording::readScriptKeyframeBinary(times, skf, _iFile, lineNum); - std::stringstream keyframeLine = std::stringstream(); SessionRecording::saveHeaderAscii(times, "script", keyframeLine); - ckf.write(keyframeLine); - SessionRecording::saveKeyframeToFile(keyframeLine.str(), _oFile); + skf.write(keyframeLine); } else { LERROR(fmt::format( @@ -157,6 +153,7 @@ void ConvertRecFormatTask::convertToAscii() { )); break; } + SessionRecording::saveKeyframeToFile(keyframeLine.str(), _oFile); lineNum++; } } From 9ba31ee0825bf9c292bae627cabc3ea33af5a71a Mon Sep 17 00:00:00 2001 From: GPayne Date: Wed, 4 Mar 2020 09:55:51 -0700 Subject: [PATCH 15/64] Added code for conversion to binary format --- .../openspace/interaction/sessionrecording.h | 12 ++-- .../tasks/convertrecformattask.cpp | 55 ++++++++++++++++++- 2 files changed, 59 insertions(+), 8 deletions(-) diff --git a/include/openspace/interaction/sessionrecording.h b/include/openspace/interaction/sessionrecording.h index 3b3372ba56..b0d523e8b9 100644 --- a/include/openspace/interaction/sessionrecording.h +++ b/include/openspace/interaction/sessionrecording.h @@ -59,6 +59,12 @@ public: const char DataFormatAsciiTag = 'A'; const char DataFormatBinaryTag = 'B'; + static const size_t keyframeHeaderSize_bytes = 33; + static const size_t saveBufferCameraSize_min = 82; + static const size_t saveBufferStringSize_max = 500; + static const size_t _saveBufferMaxSize_bytes = keyframeHeaderSize_bytes + + + saveBufferCameraSize_min + saveBufferStringSize_max; + using CallbackHandle = int; using StateChangeCallback = std::function; @@ -458,12 +464,6 @@ private: double _saveRenderingDeltaTime = 1.0 / 30.0; double _saveRenderingCurrentRecordedTime; - static const size_t keyframeHeaderSize_bytes = 33; - static const size_t saveBufferCameraSize_min = 82; - static const size_t saveBufferStringSize_max = 500; - static const size_t _saveBufferMaxSize_bytes = keyframeHeaderSize_bytes + - + saveBufferCameraSize_min - + saveBufferStringSize_max; unsigned char _keyframeBuffer[_saveBufferMaxSize_bytes]; bool _cleanupNeeded = false; diff --git a/src/interaction/tasks/convertrecformattask.cpp b/src/interaction/tasks/convertrecformattask.cpp index d54c64f09e..8b79e4477e 100644 --- a/src/interaction/tasks/convertrecformattask.cpp +++ b/src/interaction/tasks/convertrecformattask.cpp @@ -123,7 +123,7 @@ void ConvertRecFormatTask::convertToAscii() { // Check if have reached EOF if (!_iFile) { LINFO(fmt::format( - "Finished converting {} entries from playback file {}", + "Finished converting {} entries from file {}", lineNum - 1, _inFilePath )); fileReadOk = false; @@ -159,7 +159,58 @@ void ConvertRecFormatTask::convertToAscii() { } void ConvertRecFormatTask::convertToBinary() { - _outFilePath = addFileSuffix(_inFilePath, "_binary"); + SessionRecording::timestamps times; + datamessagestructures::CameraKeyframe ckf; + datamessagestructures::TimeKeyframe tkf; + datamessagestructures::ScriptMessage skf; + int lineNum = 1; + std::string lineContents; + unsigned char keyframeBuffer[SessionRecording::_saveBufferMaxSize_bytes]; + std::ofstream saveFile; + saveFile.open(_outFilePath, std::ios::binary); + size_t idx = 0; + + while (std::getline(_iFile, lineContents)) { + lineNum++; + + std::istringstream iss(lineContents); + std::string entryType; + if (!(iss >> entryType)) { + LERROR(fmt::format( + "Error reading entry type @ line {} of file {}", + lineNum, _inFilePath + )); + break; + } + + if (entryType == "camera") { + SessionRecording::readCameraKeyframeAscii(times, ckf, _inFilePath, lineNum); + SessionRecording::saveCameraKeyframeBinary(times, ckf, keyframeBuffer, + saveFile); + } + else if (entryType == "time") { + SessionRecording::readTimeKeyframeAscii(times, tkf, _inFilePath, lineNum); + SessionRecording::saveTimeKeyframeBinary(times, tkf, keyframeBuffer, + saveFile); + } + else if (entryType == "script") { + SessionRecording::readScriptKeyframeAscii(times, skf, _inFilePath, lineNum); + SessionRecording::saveScriptKeyframeBinary(times, skf, keyframeBuffer, + saveFile); + } + else { + LERROR(fmt::format( + "Unknown frame type {} @ line {} of file {}", + entryType, lineContents, _inFilePath + )); + break; + } + } + saveFile.close(); + LINFO(fmt::format( + "Finished converting {} entries from file {}", + lineNum, _inFilePath + )); } std::string ConvertRecFormatTask::addFileSuffix(const std::string& filePath, From cd7be9b87045f731a5a4b7dec0653e398bcf40d3 Mon Sep 17 00:00:00 2001 From: Gene Payne Date: Tue, 14 Jul 2020 17:19:24 -0600 Subject: [PATCH 16/64] Conversion task working for both directions --- data/tasks/sessionRecordConvertExample1.task | 7 + .../openspace/interaction/sessionrecording.h | 80 +++++++---- .../interaction/tasks/convertrecformattask.h | 5 +- include/openspace/network/messagestructures.h | 8 ++ src/CMakeLists.txt | 2 + src/interaction/sessionrecording.cpp | 100 +++++++------- src/interaction/sessionrecording_lua.inl | 4 +- .../tasks/convertrecformattask.cpp | 124 ++++++++++++------ 8 files changed, 211 insertions(+), 119 deletions(-) create mode 100644 data/tasks/sessionRecordConvertExample1.task diff --git a/data/tasks/sessionRecordConvertExample1.task b/data/tasks/sessionRecordConvertExample1.task new file mode 100644 index 0000000000..2237c462e8 --- /dev/null +++ b/data/tasks/sessionRecordConvertExample1.task @@ -0,0 +1,7 @@ +return { + { + Type = "ConvertRecFormatTask", + InputFilePath = "../../recordings/input", + OutputFilePath = "../../recordings/output" + } +} diff --git a/include/openspace/interaction/sessionrecording.h b/include/openspace/interaction/sessionrecording.h index bcfedcd918..fbfc1b5c9c 100644 --- a/include/openspace/interaction/sessionrecording.h +++ b/include/openspace/interaction/sessionrecording.h @@ -32,13 +32,21 @@ namespace openspace::interaction { +enum class SessionRecordingDataMode { + Ascii = 0, + Binary, + Unknown +}; +static const std::string SessionRecordingFileHeaderTitle = "OpenSpace_record/playback"; +static const std::string SessionRecordingHeaderCameraAscii = "camera"; +static const std::string SessionRecordingHeaderTimeAscii = "time"; +static const std::string SessionRecordingHeaderScriptAscii = "script"; +static const char SessionRecordingHeaderCameraBinary = 'c'; +static const char SessionRecordingHeaderTimeBinary = 't'; +static const char SessionRecordingHeaderScriptBinary = 's'; + class SessionRecording : public properties::PropertyOwner { public: - enum class RecordedDataMode { - Ascii = 0, - Binary - }; - enum class SessionState { Idle = 0, Recording, @@ -51,14 +59,12 @@ public: double timeSim; }; - const std::string FileHeaderTitle = "OpenSpace_record/playback"; static const size_t FileHeaderVersionLength = 5; - const char FileHeaderVersion[FileHeaderVersionLength] = { + static constexpr char FileHeaderVersion[FileHeaderVersionLength] = { '0', '0', '.', '8', '5' }; - const char DataFormatAsciiTag = 'A'; - const char DataFormatBinaryTag = 'B'; - + static const char DataFormatAsciiTag = 'A'; + static const char DataFormatBinaryTag = 'B'; static const size_t keyframeHeaderSize_bytes = 33; static const size_t saveBufferCameraSize_min = 82; static const size_t saveBufferStringSize_max = 500; @@ -114,7 +120,7 @@ public: * * \return \c true if recording to file starts without errors */ - void setRecordDataFormat(RecordedDataMode dataMode); + void setRecordDataFormat(SessionRecordingDataMode dataMode); /** * Used to stop a recording in progress. If open, the recording file will be closed, @@ -246,11 +252,12 @@ public: * * \param times reference to a timestamps structure which contains recorded times * \param kf reference to a camera keyframe which contains camera details - * \param filenameRead a string containing the playback filename + * \param currentParsingLine string containing the most current line that was read * \param lineN line number in playback file where this keyframe resides */ static void readCameraKeyframeAscii(timestamps& times, - datamessagestructures::CameraKeyframe& kf, std::string filenameRead, int lineN); + datamessagestructures::CameraKeyframe& kf, std::string currentParsingLine, + int lineN); /** * Reads a time keyframe from a binary format playback file, and populates input @@ -270,11 +277,12 @@ public: * * \param times reference to a timestamps structure which contains recorded times * \param kf reference to a time keyframe which contains time details - * \param filenameRead a string containing the playback filename + * \param currentParsingLine string containing the most current line that was read * \param lineN line number in playback file where this keyframe resides */ static void readTimeKeyframeAscii(timestamps& times, - datamessagestructures::TimeKeyframe& kf, std::string filenameRead, int lineN); + datamessagestructures::TimeKeyframe& kf, std::string currentParsingLine, + int lineN); /** * Reads a script keyframe from a binary format playback file, and populates input @@ -296,11 +304,12 @@ public: * \param times reference to a timestamps structure which contains recorded times * \param kf reference to a script keyframe which contains the size of the script * (in chars) and the text itself - * \param filenameRead a string containing the playback filename + * \param currentParsingLine string containing the most current line that was read * \param lineN line number in playback file where this keyframe resides */ static void readScriptKeyframeAscii(timestamps& times, - datamessagestructures::ScriptMessage& kf, std::string filenameRead, int lineN); + datamessagestructures::ScriptMessage& kf, std::string currentParsingLine, + int lineN); /** * Writes a camera keyframe to a binary format recording file using a CameraKeyframe @@ -377,6 +386,35 @@ public: */ static std::string readHeaderElement(std::ifstream& stream, size_t readLen_chars); + /** + * Writes a header to a binary recording file buffer + * + * \param times reference to a timestamps structure which contains recorded times + * \param type single character signifying the keyframe type + * \param kfBuffer the char buffer holding the recording info to be written + * \param idx index into write buffer (this is updated with the num of chars written) + */ + static void saveHeaderBinary(timestamps times, char type, unsigned char* kfBuffer, + size_t& idx); + + /** + * Writes a header to an ascii recording file buffer + * + * \param times reference to a timestamps structure which contains recorded times + * \param type string signifying the keyframe type + * \param line the stringstream buffer being written to + */ + static void saveHeaderAscii(timestamps times, const std::string& type, + std::stringstream& line); + + /** + * Saves a keyframe to an ascii recording file + * + * \param entry the ascii string version of the keyframe (any type) + * \param file ofstream object to write to + */ + static void saveKeyframeToFile(std::string entry, std::ofstream& file); + private: enum class RecordedType { Camera = 0, @@ -409,7 +447,6 @@ private: std::ofstream& file); static void saveKeyframeToFileBinary(unsigned char* bufferSource, size_t size, std::ofstream& file); - static void saveKeyframeToFile(std::string entry, std::ofstream& file); void addKeyframe(double timestamp, interaction::KeyframeNavigator::CameraPose keyframe); @@ -439,12 +476,7 @@ private: static void writeToFileBuffer(unsigned char* buf, size_t& idx, unsigned char c); static void writeToFileBuffer(unsigned char* buf, size_t& idx, bool b); - static void saveHeaderBinary(timestamps times, char type, - unsigned char* kfBuffer, size_t& idx); - static void saveHeaderAscii(timestamps times, const std::string& type, - std::stringstream& line); - - RecordedDataMode _recordingDataMode = RecordedDataMode::Binary; + SessionRecordingDataMode _recordingDataMode = SessionRecordingDataMode::Binary; SessionState _state = SessionState::Idle; SessionState _lastState = SessionState::Idle; std::string _playbackFilename; diff --git a/include/openspace/interaction/tasks/convertrecformattask.h b/include/openspace/interaction/tasks/convertrecformattask.h index fab8dfab51..d084bec2a6 100644 --- a/include/openspace/interaction/tasks/convertrecformattask.h +++ b/include/openspace/interaction/tasks/convertrecformattask.h @@ -53,20 +53,19 @@ public: void perform(const Task::ProgressCallback& progressCallback) override; static documentation::Documentation documentation(); void convert(); - SessionRecording::RecordedDataMode ConvertRecFormatTask::formatType(); private: void convertToAscii(); void convertToBinary(); + void determineFormatType(); std::string addFileSuffix(const std::string& filePath, const std::string& suffix); std::string _inFilePath; std::string _outFilePath; std::ifstream _iFile; std::ofstream _oFile; + SessionRecordingDataMode _fileFormatType; std::string _valueFunctionLua; - - SessionRecording sr; }; } // namespace openspace::interaction diff --git a/include/openspace/network/messagestructures.h b/include/openspace/network/messagestructures.h index bad251b66f..0131383ebe 100644 --- a/include/openspace/network/messagestructures.h +++ b/include/openspace/network/messagestructures.h @@ -429,6 +429,12 @@ struct ScriptMessage { double _timestamp; void serialize(std::vector &buffer) const { + size_t strLen = _script.size(); + size_t writeSize_bytes = sizeof(size_t); + + unsigned char const *p = reinterpret_cast(&strLen); + buffer.insert(buffer.end(), p, p + writeSize_bytes); + buffer.insert(buffer.end(), _script.begin(), _script.end()); }; @@ -486,6 +492,8 @@ struct ScriptMessage { _script.erase(); for (int i = 0; i < numScriptLines; ++i) { std::getline(iss, tmpReadbackScript); + size_t start = tmpReadbackScript.find_first_not_of(" "); + tmpReadbackScript = tmpReadbackScript.substr(start); _script.append(tmpReadbackScript); if (i < (numScriptLines - 1)) { _script.append("\n"); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b5642e724a..ae2315ffc6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -63,6 +63,7 @@ set(OPENSPACE_SOURCE ${OPENSPACE_BASE_DIR}/src/interaction/shortcutmanager_lua.inl ${OPENSPACE_BASE_DIR}/src/interaction/websocketinputstate.cpp ${OPENSPACE_BASE_DIR}/src/interaction/websocketcamerastates.cpp + ${OPENSPACE_BASE_DIR}/src/interaction/tasks/convertrecformattask.cpp ${OPENSPACE_BASE_DIR}/src/mission/mission.cpp ${OPENSPACE_BASE_DIR}/src/mission/missionmanager.cpp ${OPENSPACE_BASE_DIR}/src/mission/missionmanager_lua.inl @@ -245,6 +246,7 @@ set(OPENSPACE_HEADER ${OPENSPACE_BASE_DIR}/include/openspace/interaction/shortcutmanager.h ${OPENSPACE_BASE_DIR}/include/openspace/interaction/websocketinputstate.h ${OPENSPACE_BASE_DIR}/include/openspace/interaction/websocketcamerastates.h + ${OPENSPACE_BASE_DIR}/include/openspace/interaction/tasks/convertrecformattask.h ${OPENSPACE_BASE_DIR}/include/openspace/mission/mission.h ${OPENSPACE_BASE_DIR}/include/openspace/mission/missionmanager.h ${OPENSPACE_BASE_DIR}/include/openspace/network/parallelconnection.h diff --git a/src/interaction/sessionrecording.cpp b/src/interaction/sessionrecording.cpp index eba6a4313a..8e26877d3d 100644 --- a/src/interaction/sessionrecording.cpp +++ b/src/interaction/sessionrecording.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -36,6 +37,8 @@ #include #include #include +#include +#include #include #include #include @@ -57,7 +60,11 @@ namespace openspace::interaction { SessionRecording::SessionRecording() : properties::PropertyOwner({ "SessionRecording", "Session Recording" }) -{} +{ + auto fTask = FactoryManager::ref().factory(); + ghoul_assert(fRenderable, "No task factory existed"); + fTask->registerClass("ConvertRecFormatTask"); +} SessionRecording::~SessionRecording() {} // NOLINT @@ -66,7 +73,7 @@ void SessionRecording::deinitialize() { stopPlayback(); } -void SessionRecording::setRecordDataFormat(RecordedDataMode dataMode) { +void SessionRecording::setRecordDataFormat(SessionRecordingDataMode dataMode) { _recordingDataMode = dataMode; } @@ -102,7 +109,7 @@ bool SessionRecording::startRecording(const std::string& filename) { _playbackActive_camera = false; _playbackActive_time = false; _playbackActive_script = false; - if (_recordingDataMode == RecordedDataMode::Binary) { + if (_recordingDataMode == SessionRecordingDataMode::Binary) { _recordFile.open(absFilename, std::ios::binary); } else { @@ -115,9 +122,9 @@ bool SessionRecording::startRecording(const std::string& filename) { )); return false; } - _recordFile << FileHeaderTitle; + _recordFile << SessionRecordingFileHeaderTitle; _recordFile.write(FileHeaderVersion, FileHeaderVersionLength); - if (_recordingDataMode == RecordedDataMode::Binary) { + if (_recordingDataMode == SessionRecordingDataMode::Binary) { _recordFile << DataFormatBinaryTag; } else { @@ -180,9 +187,9 @@ bool SessionRecording::startPlayback(const std::string& filename, // Read header std::string readBackHeaderString = readHeaderElement( _playbackFile, - FileHeaderTitle.length() + SessionRecordingFileHeaderTitle.length() ); - if (readBackHeaderString != FileHeaderTitle) { + if (readBackHeaderString != SessionRecordingFileHeaderTitle) { LERROR("Specified playback file does not contain expected header."); cleanUpPlayback(); return false; @@ -190,10 +197,10 @@ bool SessionRecording::startPlayback(const std::string& filename, readHeaderElement(_playbackFile, FileHeaderVersionLength); std::string readDataMode = readHeaderElement(_playbackFile, 1); if (readDataMode[0] == DataFormatAsciiTag) { - _recordingDataMode = RecordedDataMode::Ascii; + _recordingDataMode = SessionRecordingDataMode::Ascii; } else if (readDataMode[0] == DataFormatBinaryTag) { - _recordingDataMode = RecordedDataMode::Binary; + _recordingDataMode = SessionRecordingDataMode::Binary; } else { LERROR("Unknown data type in header (should be Ascii or Binary)"); @@ -201,13 +208,14 @@ bool SessionRecording::startPlayback(const std::string& filename, } std::string throwawayNewlineChar = readHeaderElement(_playbackFile, 1); - if (_recordingDataMode == RecordedDataMode::Binary) { + if (_recordingDataMode == SessionRecordingDataMode::Binary) { //Close & re-open the file, starting from the beginning, and do dummy read // past the header, version, and data type _playbackFile.close(); _playbackFile.open(_playbackFilename, std::ifstream::in | std::ios::binary); - size_t headerSize = FileHeaderTitle.length() + FileHeaderVersionLength + - sizeof(DataFormatBinaryTag) + sizeof('\n'); + size_t headerSize = SessionRecordingFileHeaderTitle.length() + + FileHeaderVersionLength + + sizeof(DataFormatBinaryTag) + sizeof('\n'); _playbackFile.read(reinterpret_cast(&_keyframeBuffer), headerSize); } @@ -443,7 +451,7 @@ void SessionRecording::saveCameraKeyframe() { kf._timestamp - _timestampRecordStarted, global::timeManager.time().j2000Seconds() }; - if (_recordingDataMode == RecordedDataMode::Binary) { + if (_recordingDataMode == SessionRecordingDataMode::Binary) { saveCameraKeyframeBinary(times, kf, _keyframeBuffer, _recordFile); } else { @@ -479,7 +487,7 @@ void SessionRecording::saveCameraKeyframeBinary(timestamps times, { // Writing to a binary session recording file size_t idx = 0; - saveHeaderBinary(times, 'c', kfBuffer, idx); + saveHeaderBinary(times, SessionRecordingHeaderCameraBinary, kfBuffer, idx); // Writing to internal buffer, and then to file, for performance reasons std::vector writeBuffer; kf.serialize(writeBuffer); @@ -492,7 +500,7 @@ void SessionRecording::saveCameraKeyframeAscii(timestamps times, std::ofstream& file) { std::stringstream keyframeLine = std::stringstream(); - saveHeaderAscii(times, "camera", keyframeLine); + saveHeaderAscii(times, SessionRecordingHeaderCameraAscii, keyframeLine); kf.write(keyframeLine); saveKeyframeToFile(keyframeLine.str(), file); } @@ -510,7 +518,7 @@ void SessionRecording::saveTimeKeyframe() { kf._timestamp - _timestampRecordStarted, global::timeManager.time().j2000Seconds() }; - if (_recordingDataMode == RecordedDataMode::Binary) { + if (_recordingDataMode == SessionRecordingDataMode::Binary) { saveTimeKeyframeBinary(times, kf, _keyframeBuffer, _recordFile); } else { saveTimeKeyframeAscii(times, kf, _recordFile); @@ -523,7 +531,7 @@ void SessionRecording::saveTimeKeyframeBinary(timestamps times, std::ofstream& file) { size_t idx = 0; - saveHeaderBinary(times, 't', kfBuffer, idx); + saveHeaderBinary(times, SessionRecordingHeaderTimeBinary, kfBuffer, idx); std::vector writeBuffer; kf.serialize(writeBuffer); writeToFileBuffer(kfBuffer, idx, writeBuffer); @@ -535,7 +543,7 @@ void SessionRecording::saveTimeKeyframeAscii(timestamps times, std::ofstream& file) { std::stringstream keyframeLine = std::stringstream(); - saveHeaderAscii(times, "time", keyframeLine); + saveHeaderAscii(times, SessionRecordingHeaderTimeAscii, keyframeLine); kf.write(keyframeLine); saveKeyframeToFile(keyframeLine.str(), file); } @@ -554,7 +562,7 @@ void SessionRecording::saveScriptKeyframe(std::string scriptToSave) { global::timeManager.time().j2000Seconds() }; - if (_recordingDataMode == RecordedDataMode::Binary) { + if (_recordingDataMode == SessionRecordingDataMode::Binary) { saveScriptKeyframeBinary(times, sm, _keyframeBuffer, _recordFile); } else { @@ -568,11 +576,12 @@ void SessionRecording::saveScriptKeyframeBinary(timestamps times, std::ofstream& file) { size_t idx = 0; - saveHeaderBinary(times, 's', smBuffer, idx); - //Write script header to file + saveHeaderBinary(times, SessionRecordingHeaderScriptBinary, smBuffer, idx); + // Writing to internal buffer, and then to file, for performance reasons + std::vector writeBuffer; + sm.serialize(writeBuffer); + writeToFileBuffer(smBuffer, idx, writeBuffer); saveKeyframeToFileBinary(smBuffer, idx, file); - //Write script data to file - sm.write(smBuffer, idx, file); } void SessionRecording::saveScriptKeyframeAscii(timestamps times, @@ -581,7 +590,7 @@ void SessionRecording::saveScriptKeyframeAscii(timestamps times, { std::stringstream keyframeLine = std::stringstream(); - saveHeaderAscii(times, "script", keyframeLine); + saveHeaderAscii(times, SessionRecordingHeaderScriptAscii, keyframeLine); sm.write(keyframeLine); saveKeyframeToFile(keyframeLine.str(), file); } @@ -632,7 +641,7 @@ SessionRecording::SessionState SessionRecording::state() const { bool SessionRecording::playbackAddEntriesToTimeline() { bool parsingErrorsFound = false; - if (_recordingDataMode == RecordedDataMode::Binary) { + if (_recordingDataMode == SessionRecordingDataMode::Binary) { unsigned char frameType; bool fileReadOk = true; @@ -647,13 +656,13 @@ bool SessionRecording::playbackAddEntriesToTimeline() { fileReadOk = false; break; } - if (frameType == 'c') { + if (frameType == SessionRecordingHeaderCameraBinary) { playbackCamera(); } - else if (frameType == 't') { + else if (frameType == SessionRecordingHeaderTimeBinary) { playbackTimeChange(); } - else if (frameType == 's') { + else if (frameType == SessionRecordingHeaderScriptBinary) { playbackScript(); } else { @@ -682,13 +691,13 @@ bool SessionRecording::playbackAddEntriesToTimeline() { break; } - if (entryType == "camera") { + if (entryType == SessionRecordingHeaderCameraAscii) { playbackCamera(); } - else if (entryType == "time") { + else if (entryType == SessionRecordingHeaderTimeAscii) { playbackTimeChange(); } - else if (entryType == "script") { + else if (entryType == SessionRecordingHeaderScriptAscii) { playbackScript(); } else { @@ -788,7 +797,7 @@ void SessionRecording::playbackCamera() { timestamps times; datamessagestructures::CameraKeyframe kf; - if (_recordingDataMode == RecordedDataMode::Binary) { + if (_recordingDataMode == SessionRecordingDataMode::Binary) { readCameraKeyframeBinary(times, kf, _playbackFile, _playbackLineNum); } else { @@ -843,16 +852,18 @@ void SessionRecording::readCameraKeyframeBinary(timestamps& times, void SessionRecording::readCameraKeyframeAscii(timestamps& times, datamessagestructures::CameraKeyframe& kf, - std::string filenameRead, + std::string currentParsingLine, int lineN) { std::string rotationFollowing; std::string entryType; - std::istringstream iss(filenameRead); + std::istringstream iss(currentParsingLine); iss >> entryType; iss >> times.timeOs >> times.timeRec >> times.timeSim; kf.read(iss); + //ASCII format does not contain trailing timestamp so add it here + kf._timestamp = times.timeOs; if (iss.fail() || !iss.eof()) { LERROR(fmt::format("Error parsing camera line {} of playback file", lineN)); @@ -864,7 +875,7 @@ void SessionRecording::playbackTimeChange() { timestamps times; datamessagestructures::TimeKeyframe kf; - if (_recordingDataMode == RecordedDataMode::Binary) { + if (_recordingDataMode == SessionRecordingDataMode::Binary) { readTimeKeyframeBinary(times, kf, _playbackFile, _playbackLineNum); } else { readTimeKeyframeAscii(times, kf, _playbackLineParsing, _playbackLineNum); @@ -913,12 +924,12 @@ void SessionRecording::readTimeKeyframeBinary(timestamps& times, void SessionRecording::readTimeKeyframeAscii(timestamps& times, datamessagestructures::TimeKeyframe& kf, - std::string filenameRead, + std::string currentParsingLine, int lineN) { std::string entryType; - std::istringstream iss(filenameRead); + std::istringstream iss(currentParsingLine); iss >> entryType; iss >> times.timeOs >> times.timeRec >> times.timeSim; kf.read(iss); @@ -931,8 +942,8 @@ void SessionRecording::readTimeKeyframeAscii(timestamps& times, } } -static std::string SessionRecording::readHeaderElement(std::ifstream& stream, - size_t readLen_chars) +std::string SessionRecording::readHeaderElement(std::ifstream& stream, + size_t readLen_chars) { std::vector readTemp(readLen_chars); stream.read(&readTemp[0], readLen_chars); @@ -943,7 +954,7 @@ void SessionRecording::playbackScript() { timestamps times; datamessagestructures::ScriptMessage kf; - if (_recordingDataMode == RecordedDataMode::Binary) { + if (_recordingDataMode == SessionRecordingDataMode::Binary) { readScriptKeyframeBinary(times, kf, _playbackFile, _playbackLineNum); } else { readScriptKeyframeAscii(times, kf, _playbackLineParsing, _playbackLineNum); @@ -990,11 +1001,11 @@ void SessionRecording::readScriptKeyframeBinary(timestamps& times, void SessionRecording::readScriptKeyframeAscii(timestamps& times, datamessagestructures::ScriptMessage& kf, - std::string filenameRead, + std::string currentParsingLine, int lineN) { std::string entryType; - std::istringstream iss(filenameRead); + std::istringstream iss(currentParsingLine); iss >> entryType; iss >> times.timeOs >> times.timeRec >> times.timeSim; kf.read(iss); @@ -1156,11 +1167,6 @@ bool SessionRecording::doesTimelineEntryContainCamera(unsigned int index) const } bool SessionRecording::processNextNonCameraKeyframeAheadInTime() { - //LINFO(fmt::format( - // "Keyframe at {} frame={} timelineIndex={}", - // now, global::renderEngine._frameNumber, _idxTimeline - //)); - switch (getNextKeyframeType()) { case RecordedType::Camera: // Just return true since this function no longer handles camera keyframes diff --git a/src/interaction/sessionrecording_lua.inl b/src/interaction/sessionrecording_lua.inl index 8a1c2409b4..8e4761295b 100644 --- a/src/interaction/sessionrecording_lua.inl +++ b/src/interaction/sessionrecording_lua.inl @@ -40,7 +40,7 @@ int startRecording(lua_State* L) { return luaL_error(L, "filepath string is empty"); } global::sessionRecording.setRecordDataFormat( - openspace::interaction::SessionRecording::RecordedDataMode::Binary + openspace::interaction::SessionRecordingDataMode::Binary ); global::sessionRecording.startRecording(recordFilePath); @@ -63,7 +63,7 @@ int startRecordingAscii(lua_State* L) { return luaL_error(L, "filepath string is empty"); } global::sessionRecording.setRecordDataFormat( - openspace::interaction::SessionRecording::RecordedDataMode::Ascii + openspace::interaction::SessionRecordingDataMode::Ascii ); global::sessionRecording.startRecording(recordFilePath); diff --git a/src/interaction/tasks/convertrecformattask.cpp b/src/interaction/tasks/convertrecformattask.cpp index 8b79e4477e..6cbe5257db 100644 --- a/src/interaction/tasks/convertrecformattask.cpp +++ b/src/interaction/tasks/convertrecformattask.cpp @@ -51,11 +51,11 @@ ConvertRecFormatTask::ConvertRecFormatTask(const ghoul::Dictionary& dictionary) ghoul_assert(FileSys.fileExists(_inFilePath), "The filename must exist"); if (!FileSys.fileExists(_inFilePath)) { LERROR(fmt::format("Failed to load session recording file: {}", _inFilePath)); - //throw ghoul::FileNotFoundError(_inFilePath); } - - _iFile.exceptions(std::ofstream::failbit | std::ofstream::badbit); - _iFile.open(_inFilePath); + else { + _iFile.open(_inFilePath, std::ifstream::in); + determineFormatType(); + } } ConvertRecFormatTask::~ConvertRecFormatTask() { @@ -63,17 +63,42 @@ ConvertRecFormatTask::~ConvertRecFormatTask() { _oFile.close(); } -void ConvertRecFormatTask::perform(const Task::ProgressCallback& progressCallback) { +std::string ConvertRecFormatTask::description() { + std::string description = "Convert session recording file '" + _inFilePath + "' "; + if (_fileFormatType == SessionRecordingDataMode::Ascii) { + description += "(ascii format) "; + } + else if (_fileFormatType == SessionRecordingDataMode::Binary) { + description += "(binary format) "; + } + else { + description += "(UNKNOWN format) "; + } + description += "conversion to file '" + _outFilePath + "'."; + return description; +} +void ConvertRecFormatTask::perform(const Task::ProgressCallback& progressCallback) { + convert(); } void ConvertRecFormatTask::convert() { - SessionRecording::RecordedDataMode type = formatType(); + if (_fileFormatType == SessionRecordingDataMode::Ascii) { + _oFile.open(_outFilePath); + } + else if (_fileFormatType == SessionRecordingDataMode::Binary) { + _oFile.open(_outFilePath, std::ios::binary); + } + _oFile.write(SessionRecordingFileHeaderTitle.c_str(), + SessionRecordingFileHeaderTitle.length()); + _oFile.write(SessionRecording::FileHeaderVersion, + SessionRecording::FileHeaderVersionLength); + _oFile.close(); - if (type == SessionRecording::RecordedDataMode::Ascii) { + if (_fileFormatType == SessionRecordingDataMode::Ascii) { convertToBinary(); } - else if (type == SessionRecording::RecordedDataMode::Binary) { + else if (_fileFormatType == SessionRecordingDataMode::Binary) { convertToAscii(); } else { @@ -82,27 +107,31 @@ void ConvertRecFormatTask::convert() { } } -SessionRecording::RecordedDataMode ConvertRecFormatTask::formatType() { - const std::string expectedHeader = "OpenSpace_record/playback"; +void ConvertRecFormatTask::determineFormatType() { + _fileFormatType = SessionRecordingDataMode::Unknown; std::string line; - //Get first line, which is ASCII regardless of format - std::getline(_iFile, line); - if (line.substr(0, SessionRecording::FileHeaderTitle.length()) - != SessionRecording::FileHeaderTitle) + line = SessionRecording::readHeaderElement(_iFile, + SessionRecordingFileHeaderTitle.length()); + + if (line.substr(0, SessionRecordingFileHeaderTitle.length()) + != SessionRecordingFileHeaderTitle) { - LERROR(fmt::format("Session recording file {} does not have expected header.", _inFilePath)); - return SessionRecording::RecordedDataMode::Binary + 1; + LERROR(fmt::format("Session recording file {} does not have expected header.", + _inFilePath)); } else { - if (line.back() == SessionRecording::DataFormatAsciiTag) { - return SessionRecording::RecordedDataMode::Ascii; + //Read version string and throw it away (and also line feed character at end) + SessionRecording::readHeaderElement(_iFile, + SessionRecording::FileHeaderVersionLength); + line = SessionRecording::readHeaderElement(_iFile, 1); + SessionRecording::readHeaderElement(_iFile, 1); + + if (line.at(0) == SessionRecording::DataFormatAsciiTag) { + _fileFormatType = SessionRecordingDataMode::Ascii; } - else if (line.back() == SessionRecording::DataFormatBinaryTag) { - return SessionRecording::RecordedDataMode::Binary; - } - else { - return SessionRecording::RecordedDataMode::Binary + 1; + else if (line.at(0) == SessionRecording::DataFormatBinaryTag) { + _fileFormatType = SessionRecordingDataMode::Binary; } } } @@ -114,8 +143,10 @@ void ConvertRecFormatTask::convertToAscii() { datamessagestructures::ScriptMessage skf; int lineNum = 1; unsigned char frameType; - _outFilePath = addFileSuffix(_inFilePath, "_ascii"); - std::stringstream keyframeLine = std::stringstream(); + _oFile.open(_outFilePath, std::ifstream::app); + char tmpType = SessionRecording::DataFormatAsciiTag; + _oFile.write(&tmpType, 1); + _oFile.write("\n", 1); bool fileReadOk = true; while (fileReadOk) { @@ -130,20 +161,24 @@ void ConvertRecFormatTask::convertToAscii() { break; } + std::stringstream keyframeLine = std::stringstream(); keyframeLine.str(std::string()); - if (frameType == 'c') { + if (frameType == SessionRecordingHeaderCameraBinary) { SessionRecording::readCameraKeyframeBinary(times, ckf, _iFile, lineNum); - SessionRecording::saveHeaderAscii(times, "camera", keyframeLine); + SessionRecording::saveHeaderAscii(times, SessionRecordingHeaderCameraAscii, + keyframeLine); ckf.write(keyframeLine); } - else if (frameType == 't') { + else if (frameType == SessionRecordingHeaderTimeBinary) { SessionRecording::readTimeKeyframeBinary(times, tkf, _iFile, lineNum); - SessionRecording::saveHeaderAscii(times, "time", keyframeLine); + SessionRecording::saveHeaderAscii(times, SessionRecordingHeaderTimeAscii, + keyframeLine); tkf.write(keyframeLine); } - else if (frameType == 's') { + else if (frameType == SessionRecordingHeaderScriptBinary) { SessionRecording::readScriptKeyframeBinary(times, skf, _iFile, lineNum); - SessionRecording::saveHeaderAscii(times, "script", keyframeLine); + SessionRecording::saveHeaderAscii(times, SessionRecordingHeaderScriptAscii, + keyframeLine); skf.write(keyframeLine); } else { @@ -156,6 +191,7 @@ void ConvertRecFormatTask::convertToAscii() { SessionRecording::saveKeyframeToFile(keyframeLine.str(), _oFile); lineNum++; } + _oFile.close(); } void ConvertRecFormatTask::convertToBinary() { @@ -166,8 +202,10 @@ void ConvertRecFormatTask::convertToBinary() { int lineNum = 1; std::string lineContents; unsigned char keyframeBuffer[SessionRecording::_saveBufferMaxSize_bytes]; - std::ofstream saveFile; - saveFile.open(_outFilePath, std::ios::binary); + _oFile.open(_outFilePath, std::ifstream::app | std::ios::binary); + char tmpType = SessionRecording::DataFormatBinaryTag; + _oFile.write(&tmpType, 1); + _oFile.write("\n", 1); size_t idx = 0; while (std::getline(_iFile, lineContents)) { @@ -183,20 +221,20 @@ void ConvertRecFormatTask::convertToBinary() { break; } - if (entryType == "camera") { - SessionRecording::readCameraKeyframeAscii(times, ckf, _inFilePath, lineNum); + if (entryType == SessionRecordingHeaderCameraAscii) { + SessionRecording::readCameraKeyframeAscii(times, ckf, lineContents, lineNum); SessionRecording::saveCameraKeyframeBinary(times, ckf, keyframeBuffer, - saveFile); + _oFile); } - else if (entryType == "time") { - SessionRecording::readTimeKeyframeAscii(times, tkf, _inFilePath, lineNum); + else if (entryType == SessionRecordingHeaderTimeAscii) { + SessionRecording::readTimeKeyframeAscii(times, tkf, lineContents, lineNum); SessionRecording::saveTimeKeyframeBinary(times, tkf, keyframeBuffer, - saveFile); + _oFile); } - else if (entryType == "script") { - SessionRecording::readScriptKeyframeAscii(times, skf, _inFilePath, lineNum); + else if (entryType == SessionRecordingHeaderScriptAscii) { + SessionRecording::readScriptKeyframeAscii(times, skf, lineContents, lineNum); SessionRecording::saveScriptKeyframeBinary(times, skf, keyframeBuffer, - saveFile); + _oFile); } else { LERROR(fmt::format( @@ -206,7 +244,7 @@ void ConvertRecFormatTask::convertToBinary() { break; } } - saveFile.close(); + _oFile.close(); LINFO(fmt::format( "Finished converting {} entries from file {}", lineNum, _inFilePath From 273e04464755f4cacc9ac1a3be8ec119c2084887 Mon Sep 17 00:00:00 2001 From: Gene Payne Date: Wed, 15 Jul 2020 08:39:31 -0600 Subject: [PATCH 17/64] Added handling of playback file that is too large for memory --- .../openspace/interaction/sessionrecording.h | 21 ++-- src/interaction/sessionrecording.cpp | 101 ++++++++++++------ 2 files changed, 78 insertions(+), 44 deletions(-) diff --git a/include/openspace/interaction/sessionrecording.h b/include/openspace/interaction/sessionrecording.h index fbfc1b5c9c..5fb72268a4 100644 --- a/include/openspace/interaction/sessionrecording.h +++ b/include/openspace/interaction/sessionrecording.h @@ -437,21 +437,24 @@ private: double equivalentSimulationTime(double timeOs, double timeRec, double timeSim); double equivalentApplicationTime(double timeOs, double timeRec, double timeSim); - void playbackCamera(); - void playbackTimeChange(); - void playbackScript(); + bool playbackCamera(); + bool playbackTimeChange(); + bool playbackScript(); bool playbackAddEntriesToTimeline(); void signalPlaybackFinishedForComponent(RecordedType type); void findFirstCameraKeyframeInTimeline(); - static void saveStringToFile(const std::string& s, unsigned char* kfBuffer, size_t& idx, - std::ofstream& file); + static void saveStringToFile(const std::string& s, unsigned char* kfBuffer, + size_t& idx, std::ofstream& file); static void saveKeyframeToFileBinary(unsigned char* bufferSource, size_t size, std::ofstream& file); - void addKeyframe(double timestamp, - interaction::KeyframeNavigator::CameraPose keyframe); - void addKeyframe(double timestamp, datamessagestructures::TimeKeyframe keyframe); - void addKeyframe(double timestamp, std::string scriptToQueue); + bool addKeyframe(double timestamp, + interaction::KeyframeNavigator::CameraPose keyframe, int lineNum); + bool addKeyframe(double timestamp, datamessagestructures::TimeKeyframe keyframe, + int lineNum); + bool addKeyframe(double timestamp, std::string scriptToQueue, int lineNum); + bool addKeyframeToTimeline(RecordedType type, size_t indexIntoTypeKeyframes, + double timestamp, int lineNum); void moveAheadInTime(); void lookForNonCameraKeyframesThatHaveComeDue(double currTime); void updateCameraWithOrWithoutNewKeyframes(double currTime); diff --git a/src/interaction/sessionrecording.cpp b/src/interaction/sessionrecording.cpp index 8e26877d3d..4a545275b7 100644 --- a/src/interaction/sessionrecording.cpp +++ b/src/interaction/sessionrecording.cpp @@ -639,13 +639,13 @@ SessionRecording::SessionState SessionRecording::state() const { } bool SessionRecording::playbackAddEntriesToTimeline() { - bool parsingErrorsFound = false; + bool parsingStatusOk = true; if (_recordingDataMode == SessionRecordingDataMode::Binary) { unsigned char frameType; bool fileReadOk = true; - while (fileReadOk) { + while (parsingStatusOk && fileReadOk) { frameType = readFromPlayback(_playbackFile); // Check if have reached EOF if (!_playbackFile) { @@ -657,20 +657,20 @@ bool SessionRecording::playbackAddEntriesToTimeline() { break; } if (frameType == SessionRecordingHeaderCameraBinary) { - playbackCamera(); + parsingStatusOk = playbackCamera(); } else if (frameType == SessionRecordingHeaderTimeBinary) { - playbackTimeChange(); + parsingStatusOk = playbackTimeChange(); } else if (frameType == SessionRecordingHeaderScriptBinary) { - playbackScript(); + parsingStatusOk = playbackScript(); } else { LERROR(fmt::format( "Unknown frame type {} @ index {} of playback file {}", frameType, _playbackLineNum - 1, _playbackFilename )); - parsingErrorsFound = true; + parsingStatusOk = false; break; } @@ -678,7 +678,7 @@ bool SessionRecording::playbackAddEntriesToTimeline() { } } else { - while (std::getline(_playbackFile, _playbackLineParsing)) { + while (parsingStatusOk && std::getline(_playbackFile, _playbackLineParsing)) { _playbackLineNum++; std::istringstream iss(_playbackLineParsing); @@ -692,20 +692,20 @@ bool SessionRecording::playbackAddEntriesToTimeline() { } if (entryType == SessionRecordingHeaderCameraAscii) { - playbackCamera(); + parsingStatusOk = playbackCamera(); } else if (entryType == SessionRecordingHeaderTimeAscii) { - playbackTimeChange(); + parsingStatusOk = playbackTimeChange(); } else if (entryType == SessionRecordingHeaderScriptAscii) { - playbackScript(); + parsingStatusOk = playbackScript(); } else { LERROR(fmt::format( "Unknown frame type {} @ line {} of playback file {}", entryType, _playbackLineNum, _playbackFilename )); - parsingErrorsFound = true; + parsingStatusOk = false; break; } } @@ -715,7 +715,7 @@ bool SessionRecording::playbackAddEntriesToTimeline() { )); } - return !parsingErrorsFound; + return parsingStatusOk; } double SessionRecording::appropriateTimestamp(double timeOs, @@ -793,7 +793,7 @@ double SessionRecording::fixedDeltaTimeDuringFrameOutput() const { } } -void SessionRecording::playbackCamera() { +bool SessionRecording::playbackCamera() { timestamps times; datamessagestructures::CameraKeyframe kf; @@ -812,7 +812,7 @@ void SessionRecording::playbackCamera() { double timeRef = appropriateTimestamp(times.timeOs, times.timeRec, times.timeSim); interaction::KeyframeNavigator::CameraPose pbFrame(kf); - addKeyframe(timeRef, pbFrame); + return addKeyframe(timeRef, pbFrame, _playbackLineNum); } void SessionRecording::readCameraKeyframeBinary(timestamps& times, @@ -871,7 +871,7 @@ void SessionRecording::readCameraKeyframeAscii(timestamps& times, } } -void SessionRecording::playbackTimeChange() { +bool SessionRecording::playbackTimeChange() { timestamps times; datamessagestructures::TimeKeyframe kf; @@ -885,7 +885,7 @@ void SessionRecording::playbackTimeChange() { kf._time = kf._timestamp + _timestampApplicationStarted_simulation; //global::timeManager.addKeyframe(timeRef, pbFrame._timestamp); //_externInteract.timeInteraction(pbFrame); - addKeyframe(kf._timestamp, kf); + return addKeyframe(kf._timestamp, kf, _playbackLineNum); } void SessionRecording::readTimeKeyframeBinary(timestamps& times, @@ -950,7 +950,7 @@ std::string SessionRecording::readHeaderElement(std::ifstream& stream, return std::string(readTemp.begin(), readTemp.end()); } -void SessionRecording::playbackScript() { +bool SessionRecording::playbackScript() { timestamps times; datamessagestructures::ScriptMessage kf; @@ -961,7 +961,7 @@ void SessionRecording::playbackScript() { } double timeRef = appropriateTimestamp(times.timeOs, times.timeRec, times.timeSim); - addKeyframe(timeRef, kf._script); + return addKeyframe(timeRef, kf._script, _playbackLineNum); } void SessionRecording::readScriptKeyframeBinary(timestamps& times, @@ -1022,38 +1022,69 @@ void SessionRecording::readScriptKeyframeAscii(timestamps& times, } } -void SessionRecording::addKeyframe(double timestamp, - interaction::KeyframeNavigator::CameraPose keyframe) +bool SessionRecording::addKeyframe(double timestamp, + interaction::KeyframeNavigator::CameraPose keyframe, + int lineNum) { size_t indexIntoCameraKeyframesFromMainTimeline = _keyframesCamera.size(); _keyframesCamera.push_back(std::move(keyframe)); - _timeline.push_back({ + return addKeyframeToTimeline( RecordedType::Camera, - static_cast(indexIntoCameraKeyframesFromMainTimeline), - timestamp - }); + indexIntoCameraKeyframesFromMainTimeline, + timestamp, + lineNum + ); } -void SessionRecording::addKeyframe(double timestamp, - datamessagestructures::TimeKeyframe keyframe) +bool SessionRecording::addKeyframe(double timestamp, + datamessagestructures::TimeKeyframe keyframe, + int lineNum) { size_t indexIntoTimeKeyframesFromMainTimeline = _keyframesTime.size(); _keyframesTime.push_back(std::move(keyframe)); - _timeline.push_back({ + return addKeyframeToTimeline( RecordedType::Time, - static_cast(indexIntoTimeKeyframesFromMainTimeline), - timestamp - }); + indexIntoTimeKeyframesFromMainTimeline, + timestamp, + lineNum + ); } -void SessionRecording::addKeyframe(double timestamp, std::string scriptToQueue) { +bool SessionRecording::addKeyframe(double timestamp, + std::string scriptToQueue, + int lineNum) +{ size_t indexIntoScriptKeyframesFromMainTimeline = _keyframesScript.size(); _keyframesScript.push_back(std::move(scriptToQueue)); - _timeline.push_back({ + return addKeyframeToTimeline( RecordedType::Script, - static_cast(indexIntoScriptKeyframesFromMainTimeline), - timestamp - }); + indexIntoScriptKeyframesFromMainTimeline, + timestamp, + lineNum + ); +} + +bool SessionRecording::addKeyframeToTimeline(RecordedType type, + size_t indexIntoTypeKeyframes, + double timestamp, + int lineNum) +{ + try { + _timeline.push_back({ + type, + static_cast(indexIntoTypeKeyframes), + timestamp + }); + } + catch(...) { + LERROR(fmt::format( + "Timeline memory allocation error trying to add keyframe {}. " + "The playback file may be too large for system memory.", + lineNum - 1 + )); + return false; + } + return true; } void SessionRecording::moveAheadInTime() { From 5a23ae35c8ce51741d13175314e38c92846dfe1e Mon Sep 17 00:00:00 2001 From: Gene Payne Date: Wed, 15 Jul 2020 13:04:39 -0600 Subject: [PATCH 18/64] Added file extensions for session recording files --- .../openspace/interaction/sessionrecording.h | 13 +- src/interaction/sessionrecording.cpp | 120 ++++++++++++------ .../tasks/convertrecformattask.cpp | 32 +++++ 3 files changed, 123 insertions(+), 42 deletions(-) diff --git a/include/openspace/interaction/sessionrecording.h b/include/openspace/interaction/sessionrecording.h index 5fb72268a4..23635a7780 100644 --- a/include/openspace/interaction/sessionrecording.h +++ b/include/openspace/interaction/sessionrecording.h @@ -41,10 +41,13 @@ static const std::string SessionRecordingFileHeaderTitle = "OpenSpace_record/pla static const std::string SessionRecordingHeaderCameraAscii = "camera"; static const std::string SessionRecordingHeaderTimeAscii = "time"; static const std::string SessionRecordingHeaderScriptAscii = "script"; +static const std::string SessionRecordingFileExtensionBinary = ".osrec"; +static const std::string SessionRecordingFileExtensionAscii = ".osrectxt"; static const char SessionRecordingHeaderCameraBinary = 'c'; static const char SessionRecordingHeaderTimeBinary = 't'; static const char SessionRecordingHeaderScriptBinary = 's'; + class SessionRecording : public properties::PropertyOwner { public: enum class SessionState { @@ -415,6 +418,14 @@ public: */ static void saveKeyframeToFile(std::string entry, std::ofstream& file); + /** + * Checks if a specified recording file ends with a particular file extension + * + * \param filename the name of the file to record to + * \param extension the file extension to check for + */ + static bool hasFileExtension(std::string filename, std::string extension); + private: enum class RecordedType { Camera = 0, @@ -436,7 +447,7 @@ private: double appropriateTimestamp(double timeOs, double timeRec, double timeSim); double equivalentSimulationTime(double timeOs, double timeRec, double timeSim); double equivalentApplicationTime(double timeOs, double timeRec, double timeSim); - + bool handleRecordingFile(std::string filenameIn); bool playbackCamera(); bool playbackTimeChange(); bool playbackScript(); diff --git a/src/interaction/sessionrecording.cpp b/src/interaction/sessionrecording.cpp index 4a545275b7..a39e059351 100644 --- a/src/interaction/sessionrecording.cpp +++ b/src/interaction/sessionrecording.cpp @@ -77,18 +77,41 @@ void SessionRecording::setRecordDataFormat(SessionRecordingDataMode dataMode) { _recordingDataMode = dataMode; } -bool SessionRecording::startRecording(const std::string& filename) { - if (filename.find("/") != std::string::npos) { +bool SessionRecording::hasFileExtension(std::string filename, std::string extension) { + if (filename.length() <= extension.length()) { + return false; + } + else { + return (filename.substr(filename.length() - extension.length()) == extension); + } +} + +bool SessionRecording::handleRecordingFile(std::string filenameIn) { + if (filenameIn.find("/") != std::string::npos) { LERROR("Recording filename must not contain path (/) elements"); return false; } - if (!FileSys.directoryExists(absPath("${RECORDINGS}"))) { - FileSys.createDirectory( - absPath("${RECORDINGS}"), - ghoul::filesystem::FileSystem::Recursive::Yes - ); + + if (_recordingDataMode == SessionRecordingDataMode::Binary) { + if (hasFileExtension(filenameIn, SessionRecordingFileExtensionAscii)) { + LERROR("Specified filename for binary recording has ascii file extension"); + return false; + } + else if (!hasFileExtension(filenameIn, SessionRecordingFileExtensionBinary)) { + filenameIn += SessionRecordingFileExtensionBinary; + } } - const std::string absFilename = absPath("${RECORDINGS}/" + filename); + else if (_recordingDataMode == SessionRecordingDataMode::Ascii) { + if (hasFileExtension(filenameIn, SessionRecordingFileExtensionBinary)) { + LERROR("Specified filename for ascii recording has binary file extension"); + return false; + } + else if (!hasFileExtension(filenameIn, SessionRecordingFileExtensionAscii)) { + filenameIn += SessionRecordingFileExtensionAscii; + } + } + + std::string absFilename = absPath("${RECORDINGS}/" + filenameIn); if (FileSys.fileExists(absFilename)) { LERROR(fmt::format( @@ -96,19 +119,6 @@ bool SessionRecording::startRecording(const std::string& filename) { )); return false; } - if (_state == SessionState::Recording) { - LERROR("Unable to start recording while already in recording mode"); - return false; - } - else if (_state == SessionState::Playback) { - LERROR("Unable to start recording while in session playback mode"); - return false; - } - - _state = SessionState::Recording; - _playbackActive_camera = false; - _playbackActive_time = false; - _playbackActive_script = false; if (_recordingDataMode == SessionRecordingDataMode::Binary) { _recordFile.open(absFilename, std::ios::binary); } @@ -122,29 +132,57 @@ bool SessionRecording::startRecording(const std::string& filename) { )); return false; } - _recordFile << SessionRecordingFileHeaderTitle; - _recordFile.write(FileHeaderVersion, FileHeaderVersionLength); - if (_recordingDataMode == SessionRecordingDataMode::Binary) { - _recordFile << DataFormatBinaryTag; - } - else { - _recordFile << DataFormatAsciiTag; - } - _recordFile << '\n'; - - _timestampRecordStarted = global::windowDelegate.applicationTime(); - - //Record the current delta time so this is preserved in recording - double currentDeltaTime = global::timeManager.deltaTime(); - std::string scriptCommandForInitializingDeltaTime = - "openspace.time.setDeltaTime(" + std::to_string(currentDeltaTime) + ")"; - saveScriptKeyframe(scriptCommandForInitializingDeltaTime); - - LINFO("Session recording started"); - return true; } +bool SessionRecording::startRecording(const std::string& filename) { + if (_state == SessionState::Recording) { + LERROR("Unable to start recording while already in recording mode"); + return false; + } + else if (_state == SessionState::Playback) { + LERROR("Unable to start recording while in session playback mode"); + return false; + } + if (!FileSys.directoryExists(absPath("${RECORDINGS}"))) { + FileSys.createDirectory( + absPath("${RECORDINGS}"), + ghoul::filesystem::FileSystem::Recursive::Yes + ); + } + + bool recordingFileOK = handleRecordingFile(filename); + + if (recordingFileOK) { + _state = SessionState::Recording; + _playbackActive_camera = false; + _playbackActive_time = false; + _playbackActive_script = false; + + _recordFile << SessionRecordingFileHeaderTitle; + _recordFile.write(FileHeaderVersion, FileHeaderVersionLength); + if (_recordingDataMode == SessionRecordingDataMode::Binary) { + _recordFile << DataFormatBinaryTag; + } + else { + _recordFile << DataFormatAsciiTag; + } + _recordFile << '\n'; + + _timestampRecordStarted = global::windowDelegate.applicationTime(); + + //Record the current delta time so this is preserved in recording + double currentDeltaTime = global::timeManager.deltaTime(); + std::string scriptCommandForInitializingDeltaTime = + "openspace.time.setDeltaTime(" + std::to_string(currentDeltaTime) + ")"; + saveScriptKeyframe(scriptCommandForInitializingDeltaTime); + + LINFO("Session recording started"); + } + + return recordingFileOK; +} + void SessionRecording::stopRecording() { if (_state == SessionState::Recording) { _state = SessionState::Idle; diff --git a/src/interaction/tasks/convertrecformattask.cpp b/src/interaction/tasks/convertrecformattask.cpp index 6cbe5257db..de938626ec 100644 --- a/src/interaction/tasks/convertrecformattask.cpp +++ b/src/interaction/tasks/convertrecformattask.cpp @@ -83,6 +83,38 @@ void ConvertRecFormatTask::perform(const Task::ProgressCallback& progressCallbac } void ConvertRecFormatTask::convert() { + std::string expectedFileExtension_in, expectedFileExtension_out; + std::string currentFormat; + if (_fileFormatType == SessionRecordingDataMode::Binary) { + currentFormat = "binary"; + expectedFileExtension_in = SessionRecordingFileExtensionBinary; + expectedFileExtension_out = SessionRecordingFileExtensionAscii; + } + else if (_fileFormatType == SessionRecordingDataMode::Ascii) { + currentFormat = "ascii"; + expectedFileExtension_in = SessionRecordingFileExtensionAscii; + expectedFileExtension_out = SessionRecordingFileExtensionBinary; + } + + if (!SessionRecording::hasFileExtension(_inFilePath, expectedFileExtension_in)) { + LWARNING(fmt::format( + "Input filename doesn't have expected {} " + "format file extension", + currentFormat) + ); + } + if (SessionRecording::hasFileExtension(_outFilePath, expectedFileExtension_in)) { + LERROR(fmt::format( + "Output filename has {} file extension, but is conversion from {}", + currentFormat, + currentFormat) + ); + return; + } + else if (!SessionRecording::hasFileExtension(_outFilePath, expectedFileExtension_out)) { + _outFilePath += expectedFileExtension_out; + } + if (_fileFormatType == SessionRecordingDataMode::Ascii) { _oFile.open(_outFilePath); } From 3ee1a112571b14772dd0b86b795dad0ff7278f13 Mon Sep 17 00:00:00 2001 From: Gene Payne Date: Thu, 16 Jul 2020 09:49:21 -0600 Subject: [PATCH 19/64] Added support for comment line in ascii session recording file --- include/openspace/interaction/sessionrecording.h | 1 + src/interaction/sessionrecording.cpp | 3 +++ src/interaction/tasks/convertrecformattask.cpp | 3 +++ 3 files changed, 7 insertions(+) diff --git a/include/openspace/interaction/sessionrecording.h b/include/openspace/interaction/sessionrecording.h index 23635a7780..2a23252cd6 100644 --- a/include/openspace/interaction/sessionrecording.h +++ b/include/openspace/interaction/sessionrecording.h @@ -41,6 +41,7 @@ static const std::string SessionRecordingFileHeaderTitle = "OpenSpace_record/pla static const std::string SessionRecordingHeaderCameraAscii = "camera"; static const std::string SessionRecordingHeaderTimeAscii = "time"; static const std::string SessionRecordingHeaderScriptAscii = "script"; +static const std::string SessionRecordingHeaderCommentAscii = "#"; static const std::string SessionRecordingFileExtensionBinary = ".osrec"; static const std::string SessionRecordingFileExtensionAscii = ".osrectxt"; static const char SessionRecordingHeaderCameraBinary = 'c'; diff --git a/src/interaction/sessionrecording.cpp b/src/interaction/sessionrecording.cpp index a39e059351..9d31e5ba43 100644 --- a/src/interaction/sessionrecording.cpp +++ b/src/interaction/sessionrecording.cpp @@ -738,6 +738,9 @@ bool SessionRecording::playbackAddEntriesToTimeline() { else if (entryType == SessionRecordingHeaderScriptAscii) { parsingStatusOk = playbackScript(); } + else if (entryType.substr(0, 1) == SessionRecordingHeaderCommentAscii) { + continue; + } else { LERROR(fmt::format( "Unknown frame type {} @ line {} of playback file {}", diff --git a/src/interaction/tasks/convertrecformattask.cpp b/src/interaction/tasks/convertrecformattask.cpp index de938626ec..05ad083dae 100644 --- a/src/interaction/tasks/convertrecformattask.cpp +++ b/src/interaction/tasks/convertrecformattask.cpp @@ -268,6 +268,9 @@ void ConvertRecFormatTask::convertToBinary() { SessionRecording::saveScriptKeyframeBinary(times, skf, keyframeBuffer, _oFile); } + else if (entryType.substr(0, 1) == SessionRecordingHeaderCommentAscii) { + continue; + } else { LERROR(fmt::format( "Unknown frame type {} @ line {} of file {}", From 56cc8f97a5ecac76437fc3d98cf165fd367fe7d2 Mon Sep 17 00:00:00 2001 From: Emma Broman Date: Wed, 9 Sep 2020 08:31:27 +0200 Subject: [PATCH 20/64] Add delta time steps to profiles --- data/profiles/apollo8.profile | 32 ++++++++++++++++++++++ data/profiles/apollo_sites.profile | 32 ++++++++++++++++++++++ data/profiles/asteroids.profile | 32 ++++++++++++++++++++++ data/profiles/dawn.profile | 32 ++++++++++++++++++++++ data/profiles/default.profile | 32 ++++++++++++++++++++++ data/profiles/default_full.profile | 32 ++++++++++++++++++++++ data/profiles/gaia.profile | 32 ++++++++++++++++++++++ data/profiles/insight.profile | 32 ++++++++++++++++++++++ data/profiles/juno.profile | 44 +++++++++++++++--------------- data/profiles/mars.profile | 32 ++++++++++++++++++++++ data/profiles/messenger.profile | 44 +++++++++++++++--------------- data/profiles/newhorizons.profile | 27 +++++++++--------- data/profiles/osirisrex.profile | 27 +++++++++--------- data/profiles/rosetta.profile | 32 ++++++++++++++++++++++ data/profiles/touch.profile | 32 ++++++++++++++++++++++ data/profiles/voyager.profile | 44 +++++++++++++++--------------- 16 files changed, 446 insertions(+), 92 deletions(-) diff --git a/data/profiles/apollo8.profile b/data/profiles/apollo8.profile index e4cf732215..cd3eb7f4b2 100644 --- a/data/profiles/apollo8.profile +++ b/data/profiles/apollo8.profile @@ -34,3 +34,35 @@ Earth Moon Apollo8 Apollo8Launch + +#DeltaTimes +1 +2 +5 +10 +30 +60 +120 +300 +600 +1800 +3600 +7200 +10800 +21600 +43200 +86400 +172800 +345600 +604800 +1209600 +2592000 +5184000 +7776000 +15552000 +31536000 +63072000 +157680000 +315360000 +630720000 +1576800000 diff --git a/data/profiles/apollo_sites.profile b/data/profiles/apollo_sites.profile index 20cad5733f..a1fbe5ca47 100644 --- a/data/profiles/apollo_sites.profile +++ b/data/profiles/apollo_sites.profile @@ -33,3 +33,35 @@ Apollo11LemModel Apollo17LemModel Apollo11 Apollo11LunarLander + +#DeltaTimes +1 +2 +5 +10 +30 +60 +120 +300 +600 +1800 +3600 +7200 +10800 +21600 +43200 +86400 +172800 +345600 +604800 +1209600 +2592000 +5184000 +7776000 +15552000 +31536000 +63072000 +157680000 +315360000 +630720000 +1576800000 diff --git a/data/profiles/asteroids.profile b/data/profiles/asteroids.profile index 8159804b4f..752498675d 100644 --- a/data/profiles/asteroids.profile +++ b/data/profiles/asteroids.profile @@ -32,3 +32,35 @@ Earth Mars Moon Sun + +#DeltaTimes +1 +2 +5 +10 +30 +60 +120 +300 +600 +1800 +3600 +7200 +10800 +21600 +43200 +86400 +172800 +345600 +604800 +1209600 +2592000 +5184000 +7776000 +15552000 +31536000 +63072000 +157680000 +315360000 +630720000 +1576800000 diff --git a/data/profiles/dawn.profile b/data/profiles/dawn.profile index d61491cc3f..e073810117 100644 --- a/data/profiles/dawn.profile +++ b/data/profiles/dawn.profile @@ -17,3 +17,35 @@ setNavigationState DawnAsset.Dawn.Identifier 526781518487.171326, 257168309890 Dawn Ceres Vesta + +#DeltaTimes +1 +2 +5 +10 +30 +60 +120 +300 +600 +1800 +3600 +7200 +10800 +21600 +43200 +86400 +172800 +345600 +604800 +1209600 +2592000 +5184000 +7776000 +15552000 +31536000 +63072000 +157680000 +315360000 +630720000 +1576800000 diff --git a/data/profiles/default.profile b/data/profiles/default.profile index cedf4ad6d7..71508c4021 100644 --- a/data/profiles/default.profile +++ b/data/profiles/default.profile @@ -20,3 +20,35 @@ Earth Mars Moon Sun + +#DeltaTimes +1 +2 +5 +10 +30 +60 +120 +300 +600 +1800 +3600 +7200 +10800 +21600 +43200 +86400 +172800 +345600 +604800 +1209600 +2592000 +5184000 +7776000 +15552000 +31536000 +63072000 +157680000 +315360000 +630720000 +1576800000 diff --git a/data/profiles/default_full.profile b/data/profiles/default_full.profile index 6e0644ddde..0f5ccc7701 100644 --- a/data/profiles/default_full.profile +++ b/data/profiles/default_full.profile @@ -26,3 +26,35 @@ Earth Mars Moon Sun + +#DeltaTimes +1 +2 +5 +10 +30 +60 +120 +300 +600 +1800 +3600 +7200 +10800 +21600 +43200 +86400 +172800 +345600 +604800 +1209600 +2592000 +5184000 +7776000 +15552000 +31536000 +63072000 +157680000 +315360000 +630720000 +1576800000 diff --git a/data/profiles/gaia.profile b/data/profiles/gaia.profile index 9b123c9933..738c1a3715 100644 --- a/data/profiles/gaia.profile +++ b/data/profiles/gaia.profile @@ -22,3 +22,35 @@ setNavigationState "Earth" 1000000000000.0, 1000000000000.0, 1000000000000.0 #MarkNodes Gaia + +#DeltaTimes +1 +2 +5 +10 +30 +60 +120 +300 +600 +1800 +3600 +7200 +10800 +21600 +43200 +86400 +172800 +345600 +604800 +1209600 +2592000 +5184000 +7776000 +15552000 +31536000 +63072000 +157680000 +315360000 +630720000 +1576800000 diff --git a/data/profiles/insight.profile b/data/profiles/insight.profile index 8367730f5e..f0ad77fd12 100644 --- a/data/profiles/insight.profile +++ b/data/profiles/insight.profile @@ -28,3 +28,35 @@ setNavigationState insightAsset.Insight.Identifier "Root" 8.430115E0, -1.791710 #MarkNodes Insight + +#DeltaTimes +1 +2 +5 +10 +30 +60 +120 +300 +600 +1800 +3600 +7200 +10800 +21600 +43200 +86400 +172800 +345600 +604800 +1209600 +2592000 +5184000 +7776000 +15552000 +31536000 +63072000 +157680000 +315360000 +630720000 +1576800000 diff --git a/data/profiles/juno.profile b/data/profiles/juno.profile index e1d1a021d5..29887168cd 100644 --- a/data/profiles/juno.profile +++ b/data/profiles/juno.profile @@ -5,28 +5,6 @@ base scene/solarsystem/missions/juno/juno junoAsset -#Keybinding -1 Setting the simulation speed to 1 seconds per realtime second Set sim speed 1 /Simulation Speed false "openspace.time.interpolateDeltaTime(1)" -2 Setting the simulation speed to 5 seconds per realtime second Set sim speed 5 /Simulation Speed false "openspace.time.interpolateDeltaTime(5)" -3 Setting the simulation speed to 10 seconds per realtime second Set sim speed 10 /Simulation Speed false "openspace.time.interpolateDeltaTime(10)" -4 Setting the simulation speed to 20 seconds per realtime second Set sim speed 20 /Simulation Speed false "openspace.time.interpolateDeltaTime(20)" -5 Setting the simulation speed to 40 seconds per realtime second Set sim speed 40 /Simulation Speed false "openspace.time.interpolateDeltaTime(40)" -6 Setting the simulation speed to 90 seconds per realtime second Set sim speed 90 /Simulation Speed false "openspace.time.interpolateDeltaTime(90)" -7 Setting the simulation speed to 360 seconds per realtime second Set sim speed 360 /Simulation Speed false "openspace.time.interpolateDeltaTime(360)" -8 Setting the simulation speed to 720 seconds per realtime second Set sim speed 720 /Simulation Speed false "openspace.time.interpolateDeltaTime(720)" -9 Setting the simulation speed to 2880 seconds per realtime second Set sim speed 2880 /Simulation Speed false "openspace.time.interpolateDeltaTime(2880)" -0 Setting the simulation speed to 14400 seconds per realtime second Set sim speed 14400 /Simulation Speed false "openspace.time.interpolateDeltaTime(14400)" -Shift+1 Setting the simulation speed to 28800 seconds per realtime second Set sim speed 28800 /Simulation Speed false "openspace.time.interpolateDeltaTime(28800)" -Shift+2 Setting the simulation speed to 57600 seconds per realtime second Set sim speed 57600 /Simulation Speed false "openspace.time.interpolateDeltaTime(57600)" -Shift+3 Setting the simulation speed to 115200 seconds per realtime second Set sim speed 115200 /Simulation Speed false "openspace.time.interpolateDeltaTime(115200)" -Shift+4 Setting the simulation speed to 230400 seconds per realtime second Set sim speed 230400 /Simulation Speed false "openspace.time.interpolateDeltaTime(230400)" -Shift+5 Setting the simulation speed to 460800 seconds per realtime second Set sim speed 460800 /Simulation Speed false "openspace.time.interpolateDeltaTime(460800)" -Shift+6 Setting the simulation speed to 921600 seconds per realtime second Set sim speed 921600 /Simulation Speed false "openspace.time.interpolateDeltaTime(921600)" -Shift+7 Setting the simulation speed to 1843200 seconds per realtime second Set sim speed 1843200 /Simulation Speed false "openspace.time.interpolateDeltaTime(1843200)" -Shift+8 Setting the simulation speed to 3686400 seconds per realtime second Set sim speed 3686400 /Simulation Speed false "openspace.time.interpolateDeltaTime(3686400)" -Shift+9 Setting the simulation speed to 7372800 seconds per realtime second Set sim speed 7372800 /Simulation Speed false "openspace.time.interpolateDeltaTime(7372800)" -Shift+0 Setting the simulation speed to 14745600 seconds per realtime second Set sim speed 14745600 /Simulation Speed false "openspace.time.interpolateDeltaTime(14745600)" - #Time absolute 2016-07-01T10:05:00.00 @@ -36,3 +14,25 @@ setNavigationState junoAsset.Juno.Identifier "Root" 1.243398E8, 7.176068E7, -1. #MarkNodes Jupiter Juno + +#DeltaTimes +1 +5 +10 +20 +40 +90 +360 +720 +2880 +14400 +28800 +57600 +115200 +230400 +460800 +921600 +1843200 +3686400 +7372800 +14745600 diff --git a/data/profiles/mars.profile b/data/profiles/mars.profile index bcd26230b8..2a004a968a 100644 --- a/data/profiles/mars.profile +++ b/data/profiles/mars.profile @@ -17,6 +17,38 @@ Mars Insight Perseverance +#DeltaTimes +1 +2 +5 +10 +30 +60 +120 +300 +600 +1800 +3600 +7200 +10800 +21600 +43200 +86400 +172800 +345600 +604800 +1209600 +2592000 +5184000 +7776000 +15552000 +31536000 +63072000 +157680000 +315360000 +630720000 +1576800000 + #AdditionalScripts local insightEDLShortcuts = sceneHelper.extractShortcuts({"Insight Height Offset", "Enable HiRISE", "Insight EDL Time", "Insight EDL NavigationState"}, insightShortcuts.Shortcuts) local insightDisableShortcuts = sceneHelper.extractShortcuts({"Default Height Offset", "Disable HiRISE"}, insightShortcuts.Shortcuts) diff --git a/data/profiles/messenger.profile b/data/profiles/messenger.profile index bdbb7d2722..d70a5ccaae 100644 --- a/data/profiles/messenger.profile +++ b/data/profiles/messenger.profile @@ -9,28 +9,6 @@ base scene/solarsystem/missions/messenger/dashboard scene/solarsystem/missions/messenger/messengerSC -#Keybinding -1 Setting the simulation speed to 1 seconds per realtime second Set sim speed 1 /Simulation Speed false "openspace.time.interpolateDeltaTime(1)" -2 Setting the simulation speed to 5 seconds per realtime second Set sim speed 5 /Simulation Speed false "openspace.time.interpolateDeltaTime(5)" -3 Setting the simulation speed to 10 seconds per realtime second Set sim speed 10 /Simulation Speed false "openspace.time.interpolateDeltaTime(10)" -4 Setting the simulation speed to 20 seconds per realtime second Set sim speed 20 /Simulation Speed false "openspace.time.interpolateDeltaTime(20)" -5 Setting the simulation speed to 40 seconds per realtime second Set sim speed 40 /Simulation Speed false "openspace.time.interpolateDeltaTime(40)" -6 Setting the simulation speed to 90 seconds per realtime second Set sim speed 90 /Simulation Speed false "openspace.time.interpolateDeltaTime(90)" -7 Setting the simulation speed to 360 seconds per realtime second Set sim speed 360 /Simulation Speed false "openspace.time.interpolateDeltaTime(360)" -8 Setting the simulation speed to 720 seconds per realtime second Set sim speed 720 /Simulation Speed false "openspace.time.interpolateDeltaTime(720)" -9 Setting the simulation speed to 2880 seconds per realtime second Set sim speed 2880 /Simulation Speed false "openspace.time.interpolateDeltaTime(2880)" -0 Setting the simulation speed to 14400 seconds per realtime second Set sim speed 14400 /Simulation Speed false "openspace.time.interpolateDeltaTime(14400)" -Shift+1 Setting the simulation speed to 28800 seconds per realtime second Set sim speed 28800 /Simulation Speed false "openspace.time.interpolateDeltaTime(28800)" -Shift+2 Setting the simulation speed to 57600 seconds per realtime second Set sim speed 57600 /Simulation Speed false "openspace.time.interpolateDeltaTime(57600)" -Shift+3 Setting the simulation speed to 115200 seconds per realtime second Set sim speed 115200 /Simulation Speed false "openspace.time.interpolateDeltaTime(115200)" -Shift+4 Setting the simulation speed to 230400 seconds per realtime second Set sim speed 230400 /Simulation Speed false "openspace.time.interpolateDeltaTime(230400)" -Shift+5 Setting the simulation speed to 460800 seconds per realtime second Set sim speed 460800 /Simulation Speed false "openspace.time.interpolateDeltaTime(460800)" -Shift+6 Setting the simulation speed to 921600 seconds per realtime second Set sim speed 921600 /Simulation Speed false "openspace.time.interpolateDeltaTime(921600)" -Shift+7 Setting the simulation speed to 1843200 seconds per realtime second Set sim speed 1843200 /Simulation Speed false "openspace.time.interpolateDeltaTime(1843200)" -Shift+8 Setting the simulation speed to 3686400 seconds per realtime second Set sim speed 3686400 /Simulation Speed false "openspace.time.interpolateDeltaTime(3686400)" -Shift+9 Setting the simulation speed to 7372800 seconds per realtime second Set sim speed 7372800 /Simulation Speed false "openspace.time.interpolateDeltaTime(7372800)" -Shift+0 Setting the simulation speed to 14745600 seconds per realtime second Set sim speed 14745600 /Simulation Speed false "openspace.time.interpolateDeltaTime(14745600)" - #Time absolute 2011 MAY 13 00:05:18 @@ -41,3 +19,25 @@ setNavigationState "Mercury" "Root" 2.423690E11, 1.979038E11, -2.241483E10 -0.4 Mercury Messenger Sun + +#DeltaTimes +1 +5 +10 +20 +40 +90 +360 +720 +2880 +14400 +28800 +57600 +115200 +230400 +460800 +921600 +1843200 +3686400 +7372800 +14745600 diff --git a/data/profiles/newhorizons.profile b/data/profiles/newhorizons.profile index f7be9639a7..227617eb55 100644 --- a/data/profiles/newhorizons.profile +++ b/data/profiles/newhorizons.profile @@ -38,19 +38,6 @@ m Draws the instrument field of views in a solid color or as lines. Toggle instr Shift+t Toggles the visibility of the shadow visualization of Pluto and Charon. Toggle Shadows /New Horizons false renderableHelper.toggle('Scene.PlutoShadow') .. renderableHelper.toggle('Scene.CharonShadow') t Toggles the trail of New Horizons. Toggle NH Trail /New Horizons false renderableHelper.toggle('Scene.NewHorizonsTrailPluto') h Disables visibility of the trails Hide Trails /Rendering false "local list = openspace.getProperty('*Trail.Renderable.Enabled'); for _,v in pairs(list) do openspace.setPropertyValueSingle(v, not openspace.getPropertyValue(v)) end" -1 Setting the simulation speed to 1 seconds per realtime second Set sim speed 1 /Simulation Speed false "openspace.time.interpolateDeltaTime(1)" -2 Setting the simulation speed to 5 seconds per realtime second Set sim speed 5 /Simulation Speed false "openspace.time.interpolateDeltaTime(5)" -3 Setting the simulation speed to 10 seconds per realtime second Set sim speed 10 /Simulation Speed false "openspace.time.interpolateDeltaTime(10)" -4 Setting the simulation speed to 20 seconds per realtime second Set sim speed 20 /Simulation Speed false "openspace.time.interpolateDeltaTime(20)" -5 Setting the simulation speed to 40 seconds per realtime second Set sim speed 40 /Simulation Speed false "openspace.time.interpolateDeltaTime(40)" -6 Setting the simulation speed to 60 seconds per realtime second Set sim speed 60 /Simulation Speed false "openspace.time.interpolateDeltaTime(60)" -7 Setting the simulation speed to 120 seconds per realtime second Set sim speed 120 /Simulation Speed false "openspace.time.interpolateDeltaTime(120)" -8 Setting the simulation speed to 360 seconds per realtime second Set sim speed 360 /Simulation Speed false "openspace.time.interpolateDeltaTime(360)" -9 Setting the simulation speed to 540 seconds per realtime second Set sim speed 540 /Simulation Speed false "openspace.time.interpolateDeltaTime(540)" -0 Setting the simulation speed to 1080 seconds per realtime second Set sim speed 1080 /Simulation Speed false "openspace.time.interpolateDeltaTime(1080)" -Shift+1 Setting the simulation speed to 2160 seconds per realtime second Set sim speed 2160 /Simulation Speed false "openspace.time.interpolateDeltaTime(2160)" -Shift+2 Setting the simulation speed to 4320 seconds per realtime second Set sim speed 4320 /Simulation Speed false "openspace.time.interpolateDeltaTime(4320)" -Shift+3 Setting the simulation speed to 8640 seconds per realtime second Set sim speed 8640 /Simulation Speed false "openspace.time.interpolateDeltaTime(8640)" #Time absolute 2015-07-14T08:00:00.00 @@ -62,3 +49,17 @@ setNavigationState "NewHorizons" "Root" -6.572656E1, -7.239404E1, -2.111890E1 0 Pluto NewHorizons Charon + +#DeltaTimes +1 +5 +10 +20 +40 +120 +360 +540 +1080 +2160 +4320 +8640 diff --git a/data/profiles/osirisrex.profile b/data/profiles/osirisrex.profile index c7b783877e..044e83b2bc 100644 --- a/data/profiles/osirisrex.profile +++ b/data/profiles/osirisrex.profile @@ -22,19 +22,6 @@ F9 Sets the time to the preliminary survey of Bennu Set Bennu survey time /Missi F10 Sets the time to the orbital B event Set orbital B event time /Missions/Osiris Rex false "openspace.printInfo('Set time: Orbital B'); openspace.time.setTime('2019-APR-08 10:35:27.186')" F11 Sets the time to the recon event Set recon event time /Missions/Osiris Rex false "openspace.printInfo('Set time: Recon'); openspace.time.setTime('2019-MAY-25 03:50:31.195')" q Toggles the visibility of the text marking the location of the Sun Toggle Sun marker /Missions/Osiris Rex false propertyHelper.invert('Scene.SunMarker.Renderable.Enabled') -1 Setting the simulation speed to 1 seconds per realtime second Set sim speed 1 /Simulation Speed false "openspace.time.interpolateDeltaTime(1)" -2 Setting the simulation speed to 5 seconds per realtime second Set sim speed 5 /Simulation Speed false "openspace.time.interpolateDeltaTime(5)" -3 Setting the simulation speed to 10 seconds per realtime second Set sim speed 10 /Simulation Speed false "openspace.time.interpolateDeltaTime(10)" -4 Setting the simulation speed to 20 seconds per realtime second Set sim speed 20 /Simulation Speed false "openspace.time.interpolateDeltaTime(20)" -5 Setting the simulation speed to 40 seconds per realtime second Set sim speed 40 /Simulation Speed false "openspace.time.interpolateDeltaTime(40)" -6 Setting the simulation speed to 60 seconds per realtime second Set sim speed 60 /Simulation Speed false "openspace.time.interpolateDeltaTime(60)" -7 Setting the simulation speed to 120 seconds per realtime second Set sim speed 120 /Simulation Speed false "openspace.time.interpolateDeltaTime(120)" -8 Setting the simulation speed to 360 seconds per realtime second Set sim speed 360 /Simulation Speed false "openspace.time.interpolateDeltaTime(360)" -9 Setting the simulation speed to 540 seconds per realtime second Set sim speed 540 /Simulation Speed false "openspace.time.interpolateDeltaTime(540)" -0 Setting the simulation speed to 1080 seconds per realtime second Set sim speed 1080 /Simulation Speed false "openspace.time.interpolateDeltaTime(1080)" -Shift+1 Setting the simulation speed to 2160 seconds per realtime second Set sim speed 2160 /Simulation Speed false "openspace.time.interpolateDeltaTime(2160)" -Shift+2 Setting the simulation speed to 4320 seconds per realtime second Set sim speed 4320 /Simulation Speed false "openspace.time.interpolateDeltaTime(4320)" -Shift+3 Setting the simulation speed to 8640 seconds per realtime second Set sim speed 8640 /Simulation Speed false "openspace.time.interpolateDeltaTime(8640)" #Time absolute 2018 10 30 23:00:00.500 @@ -46,3 +33,17 @@ setNavigationState OsirisRexAsset.OsirisRex.Identifier 26974590199.661884, 763 OsirisRex BennuBarycenter Earth + +#DeltaTimes +1 +5 +10 +20 +40 +120 +360 +540 +1080 +2160 +4320 +8640 diff --git a/data/profiles/rosetta.profile b/data/profiles/rosetta.profile index dd27b61191..da3dba1455 100644 --- a/data/profiles/rosetta.profile +++ b/data/profiles/rosetta.profile @@ -37,3 +37,35 @@ setNavigationState Comet67PAsset.Comet67P.Identifier "Root" -7.294781E5 , -6.65 67P Rosetta Philae + +#DeltaTimes +1 +2 +5 +10 +30 +60 +120 +300 +600 +1800 +3600 +7200 +10800 +21600 +43200 +86400 +172800 +345600 +604800 +1209600 +2592000 +5184000 +7776000 +15552000 +31536000 +63072000 +157680000 +315360000 +630720000 +1576800000 diff --git a/data/profiles/touch.profile b/data/profiles/touch.profile index 8fe818c78b..d725a02f2a 100644 --- a/data/profiles/touch.profile +++ b/data/profiles/touch.profile @@ -24,3 +24,35 @@ setNavigationState earthAsset.Earth.Identifier 58.5877,16.1924,20000000 Earth Mars Moon + +#DeltaTimes +1 +2 +5 +10 +30 +60 +120 +300 +600 +1800 +3600 +7200 +10800 +21600 +43200 +86400 +172800 +345600 +604800 +1209600 +2592000 +5184000 +7776000 +15552000 +31536000 +63072000 +157680000 +315360000 +630720000 +1576800000 diff --git a/data/profiles/voyager.profile b/data/profiles/voyager.profile index a95f48581e..de9bde296a 100644 --- a/data/profiles/voyager.profile +++ b/data/profiles/voyager.profile @@ -13,28 +13,6 @@ scene/solarsystem/missions/voyager/voyager1 VoyagerAsset scene/solarsystem/missions/voyager/voyager2 scene/solarsystem/missions/voyager/dashboard -#Keybinding -1 Setting the simulation speed to 1 seconds per realtime second Set sim speed 1 /Simulation Speed false "openspace.time.interpolateDeltaTime(1)" -2 Setting the simulation speed to 5 seconds per realtime second Set sim speed 5 /Simulation Speed false "openspace.time.interpolateDeltaTime(5)" -3 Setting the simulation speed to 10 seconds per realtime second Set sim speed 10 /Simulation Speed false "openspace.time.interpolateDeltaTime(10)" -4 Setting the simulation speed to 20 seconds per realtime second Set sim speed 20 /Simulation Speed false "openspace.time.interpolateDeltaTime(20)" -5 Setting the simulation speed to 40 seconds per realtime second Set sim speed 40 /Simulation Speed false "openspace.time.interpolateDeltaTime(40)" -6 Setting the simulation speed to 90 seconds per realtime second Set sim speed 90 /Simulation Speed false "openspace.time.interpolateDeltaTime(90)" -7 Setting the simulation speed to 360 seconds per realtime second Set sim speed 360 /Simulation Speed false "openspace.time.interpolateDeltaTime(360)" -8 Setting the simulation speed to 720 seconds per realtime second Set sim speed 720 /Simulation Speed false "openspace.time.interpolateDeltaTime(720)" -9 Setting the simulation speed to 2880 seconds per realtime second Set sim speed 2880 /Simulation Speed false "openspace.time.interpolateDeltaTime(2880)" -0 Setting the simulation speed to 14400 seconds per realtime second Set sim speed 14400 /Simulation Speed false "openspace.time.interpolateDeltaTime(14400)" -Shift+1 Setting the simulation speed to 28800 seconds per realtime second Set sim speed 28800 /Simulation Speed false "openspace.time.interpolateDeltaTime(28800)" -Shift+2 Setting the simulation speed to 57600 seconds per realtime second Set sim speed 57600 /Simulation Speed false "openspace.time.interpolateDeltaTime(57600)" -Shift+3 Setting the simulation speed to 115200 seconds per realtime second Set sim speed 115200 /Simulation Speed false "openspace.time.interpolateDeltaTime(115200)" -Shift+4 Setting the simulation speed to 230400 seconds per realtime second Set sim speed 230400 /Simulation Speed false "openspace.time.interpolateDeltaTime(230400)" -Shift+5 Setting the simulation speed to 460800 seconds per realtime second Set sim speed 460800 /Simulation Speed false "openspace.time.interpolateDeltaTime(460800)" -Shift+6 Setting the simulation speed to 921600 seconds per realtime second Set sim speed 921600 /Simulation Speed false "openspace.time.interpolateDeltaTime(921600)" -Shift+7 Setting the simulation speed to 1843200 seconds per realtime second Set sim speed 1843200 /Simulation Speed false "openspace.time.interpolateDeltaTime(1843200)" -Shift+8 Setting the simulation speed to 3686400 seconds per realtime second Set sim speed 3686400 /Simulation Speed false "openspace.time.interpolateDeltaTime(3686400)" -Shift+9 Setting the simulation speed to 7372800 seconds per realtime second Set sim speed 7372800 /Simulation Speed false "openspace.time.interpolateDeltaTime(7372800)" -Shift+0 Setting the simulation speed to 14745600 seconds per realtime second Set sim speed 14745600 /Simulation Speed false "openspace.time.interpolateDeltaTime(14745600)" - #Property setPropertyValueSingle Scene.Pluto.Renderable.Enabled false setPropertyValueSingle Scene.Charon.Renderable.Enabled false @@ -54,3 +32,25 @@ Jupiter Saturn Uranus Neptune + +#DeltaTimes +1 +5 +10 +20 +40 +90 +360 +720 +2880 +14400 +28800 +57600 +115200 +230400 +460800 +921600 +1843200 +3686400 +7372800 +14745600 From b1550d5f8fbb6b63fd37c42334cf1de9f26606ee Mon Sep 17 00:00:00 2001 From: Emma Broman Date: Thu, 10 Sep 2020 16:38:08 +0200 Subject: [PATCH 21/64] Fix typo --- src/interaction/keybindingmanager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/interaction/keybindingmanager.cpp b/src/interaction/keybindingmanager.cpp index 71d6d031e5..c70b08d30a 100644 --- a/src/interaction/keybindingmanager.cpp +++ b/src/interaction/keybindingmanager.cpp @@ -145,7 +145,7 @@ void KeybindingManager::removeKeyBinding(const std::string& key) { it = _keyLua.erase(it); } else { - // We if it is not, we continue iteration + // If it is not, we continue iteration ++it; } } From 5d895dd266ee0e7177d53dba55ddfca58645eb42 Mon Sep 17 00:00:00 2001 From: Emma Broman Date: Mon, 21 Sep 2020 09:34:35 +0200 Subject: [PATCH 22/64] Add keybindings for delta time steps --- include/openspace/util/timemanager.h | 2 + src/util/timemanager.cpp | 88 ++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) diff --git a/include/openspace/util/timemanager.h b/include/openspace/util/timemanager.h index 6bb8781e4e..5d41edabec 100644 --- a/include/openspace/util/timemanager.h +++ b/include/openspace/util/timemanager.h @@ -129,6 +129,8 @@ private: TimeKeyframeData interpolate(const Keyframe& past, const Keyframe& future, double time); + void addDeltaTimesKeybindings(); + Timeline _timeline; SyncData