diff --git a/include/openspace/interaction/sessionrecording.h b/include/openspace/interaction/sessionrecording.h index 4e2ce1faef..c71c528975 100644 --- a/include/openspace/interaction/sessionrecording.h +++ b/include/openspace/interaction/sessionrecording.h @@ -30,6 +30,7 @@ #include #include #include +#include namespace openspace::interaction { @@ -117,6 +118,20 @@ public: */ double fixedDeltaTimeDuringFrameOutput() const; + /** + * Returns the number of microseconds that have elapsed since playback started, if + * playback is set to be in the mode where a screenshot is captured with every + * rendered frame (enableTakeScreenShotDuringPlayback() is used to enable this mode). + * At the start of playback, this timer is set to the current steady_clock value. + * However, during playback it is incremented by the fixed framerate of the playback + * rather than the actual clock value (as in normal operation). + * + * \returns number of microseconds elapsed since playback started in terms of the + * number of rendered frames multiplied by the fixed time increment per + * frame + */ + std::chrono::steady_clock::time_point currentPlaybackInterpolationTime() const; + /** * Starts a recording session, which will save data to the provided filename * according to the data format specified, and will continue until recording is @@ -627,6 +642,9 @@ protected: bool _saveRenderingDuringPlayback = false; double _saveRenderingDeltaTime = 1.0 / 30.0; double _saveRenderingCurrentRecordedTime; + std::chrono::steady_clock::duration _saveRenderingDeltaTime_interpolation_usec; + std::chrono::steady_clock::time_point _saveRenderingCurrentRecordedTime_interpolation; + long long _saveRenderingClockInterpolation_countsPerSec; unsigned char _keyframeBuffer[_saveBufferMaxSize_bytes]; diff --git a/src/interaction/sessionrecording.cpp b/src/interaction/sessionrecording.cpp index 4e5b9d8a93..0d83cf4f99 100644 --- a/src/interaction/sessionrecording.cpp +++ b/src/interaction/sessionrecording.cpp @@ -324,11 +324,15 @@ bool SessionRecording::startPlayback(std::string& filename, return false; } //Set time reference mode + using namespace std::chrono; double now = global::windowDelegate->applicationTime(); _timestampPlaybackStarted_application = now; _timestampPlaybackStarted_simulation = global::timeManager->time().j2000Seconds(); _timestampApplicationStarted_simulation = _timestampPlaybackStarted_simulation - now; _playbackTimeReferenceMode = timeMode; + _saveRenderingCurrentRecordedTime_interpolation = steady_clock::now(); + _saveRenderingClockInterpolation_countsPerSec = + system_clock::duration::period::den / system_clock::duration::period::num; //Set playback flags to true for all modes _playbackActive_camera = true; @@ -407,6 +411,8 @@ void SessionRecording::signalPlaybackFinishedForComponent(RecordedType type) { void SessionRecording::enableTakeScreenShotDuringPlayback(int fps) { _saveRenderingDuringPlayback = true; _saveRenderingDeltaTime = 1.0 / fps; + _saveRenderingDeltaTime_interpolation_usec = + std::chrono::microseconds(static_cast(_saveRenderingDeltaTime * 1000000)); } void SessionRecording::disableTakeScreenShotDuringPlayback() { @@ -907,6 +913,10 @@ double SessionRecording::fixedDeltaTimeDuringFrameOutput() const { } } +std::chrono::steady_clock::time_point SessionRecording::currentPlaybackInterpolationTime() const { + return _saveRenderingCurrentRecordedTime_interpolation; +} + bool SessionRecording::playbackCamera() { Timestamps times; datamessagestructures::CameraKeyframe kf; @@ -1388,6 +1398,8 @@ bool SessionRecording::addKeyframeToTimeline(RecordedType type, } void SessionRecording::moveAheadInTime() { + using namespace std::chrono; + double currTime = currentTime(); lookForNonCameraKeyframesThatHaveComeDue(currTime); updateCameraWithOrWithoutNewKeyframes(currTime); @@ -1398,6 +1410,8 @@ void SessionRecording::moveAheadInTime() { global::navigationHandler->orbitalNavigator().anchorNode(); const Renderable* focusRenderable = focusNode->renderable(); if (!focusRenderable || focusRenderable->renderedWithDesiredData()) { + _saveRenderingCurrentRecordedTime_interpolation += + _saveRenderingDeltaTime_interpolation_usec; _saveRenderingCurrentRecordedTime += _saveRenderingDeltaTime; global::renderEngine->takeScreenshot(); } diff --git a/src/scene/scene.cpp b/src/scene/scene.cpp index d364354be3..ababedeea9 100644 --- a/src/scene/scene.cpp +++ b/src/scene/scene.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -494,9 +495,14 @@ void Scene::addPropertyInterpolation(properties::Property* prop, float durationS ghoul::easingFunction(easingFunction); // First check if the current property already has an interpolation information + std::chrono::steady_clock::time_point now = ( + global::sessionRecording->isSavingFramesDuringPlayback() ? + global::sessionRecording->currentPlaybackInterpolationTime() : + std::chrono::steady_clock::now() + ); for (PropertyInterpolationInfo& info : _propertyInterpolationInfos) { if (info.prop == prop) { - info.beginTime = std::chrono::steady_clock::now(); + info.beginTime = now; info.durationSeconds = durationSeconds; info.easingFunction = func; // If we found it, we can break since we make sure that each property is only @@ -543,8 +549,13 @@ void Scene::updateInterpolations() { using namespace std::chrono; - auto now = steady_clock::now(); - + steady_clock::time_point now; + if (global::sessionRecording->isSavingFramesDuringPlayback()) { + now = global::sessionRecording->currentPlaybackInterpolationTime(); + } + else { + now = steady_clock::now(); + } // First, let's update the properties for (PropertyInterpolationInfo& i : _propertyInterpolationInfos) { long long usPassed = duration_cast(