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;