mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-04-26 14:08:53 -05:00
Feature/time interpolation (#669)
* Initial implementation * Better approximation of target time * Correctly use double precision for time passing * Cleanup * Adding proportional adjustment of delta time at end of interpolation * Keyframe based time interpolation * Add property for time interpolation duration. Move time interpolation methods to TimeManager. * Fix bugs with time gui * Make several clicks on delta time buttons work as expected * Clean up * Improve time interpolation for parallel connection * Improve time API. Fix time interpolation bugs. * Fix mac compile issue * Add hour button * Add missing + sign * Remove newer images from projection buffer when going back in time * Add comment about clearing projection buffer * Fix bug with jumping time in parallel connection * Rename integrateFromTime to previousFrameTime * Compile fix for iswa module * Address code review comments * Code cleanup * Fix bug causig unsmooth behaviour when pausing while interpolating in time
This commit is contained in:
@@ -65,13 +65,23 @@ public:
|
||||
*/
|
||||
operator const T&() const;
|
||||
|
||||
/**
|
||||
* Explicitly access data
|
||||
*/
|
||||
T& data();
|
||||
|
||||
/**
|
||||
* Explicitly access const data
|
||||
*/
|
||||
const T& data() const;
|
||||
|
||||
protected:
|
||||
virtual void encode(SyncBuffer* syncBuffer) override;
|
||||
virtual void decode(SyncBuffer* syncBuffer) override;
|
||||
virtual void postSync(bool isMaster) override;
|
||||
|
||||
T data;
|
||||
T doubleBufferedData;
|
||||
T _data;
|
||||
T _doubleBufferedData;
|
||||
std::mutex _mutex;
|
||||
};
|
||||
|
||||
|
||||
@@ -27,38 +27,48 @@
|
||||
namespace openspace {
|
||||
|
||||
template<class T>
|
||||
SyncData<T>::SyncData(const T& val) : data(val) {}
|
||||
SyncData<T>::SyncData(const T& val) : _data(val) {}
|
||||
|
||||
template<class T>
|
||||
SyncData<T>::SyncData(const SyncData<T>& o) : data(o.data) {}
|
||||
SyncData<T>::SyncData(const SyncData<T>& o) : _data(o._data) {}
|
||||
|
||||
template<class T>
|
||||
SyncData<T>& SyncData<T>::operator=(const T& rhs) {
|
||||
data = rhs;
|
||||
_data = rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
SyncData<T>::operator T&() {
|
||||
return data;
|
||||
return _data;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
SyncData<T>::operator const T&() const {
|
||||
return data;
|
||||
return _data;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T& SyncData<T>::data() {
|
||||
return _data;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
const T& SyncData<T>::data() const {
|
||||
return _data;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void SyncData<T>::encode(SyncBuffer* syncBuffer) {
|
||||
_mutex.lock();
|
||||
syncBuffer->encode(data);
|
||||
syncBuffer->encode(_data);
|
||||
_mutex.unlock();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void SyncData<T>::decode(SyncBuffer* syncBuffer) {
|
||||
_mutex.lock();
|
||||
syncBuffer->decode(doubleBufferedData);
|
||||
syncBuffer->decode(_doubleBufferedData);
|
||||
_mutex.unlock();
|
||||
}
|
||||
|
||||
@@ -67,7 +77,7 @@ void SyncData<T>::postSync(bool isMaster) {
|
||||
// apply synced update
|
||||
if (!isMaster) {
|
||||
_mutex.lock();
|
||||
data = doubleBufferedData;
|
||||
_data = _doubleBufferedData;
|
||||
_mutex.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,22 +89,16 @@ public:
|
||||
* Sets the current time to the specified value in seconds past the J2000 epoch. This
|
||||
* value can be negative to represent dates before the epoch.
|
||||
* \param value The number of seconds after the J2000 epoch
|
||||
* \param requireJump Whether or not the time change is big enough to require a
|
||||
* time-jump; defaults to true as most calls to set time will require recomputation of
|
||||
* planetary paths etc.
|
||||
*/
|
||||
void setTime(double j2000Seconds, bool requireJump = true);
|
||||
void setTime(double j2000Seconds);
|
||||
|
||||
/**
|
||||
* Sets the current time to the specified value given as a Spice compliant string as
|
||||
* described in the Spice documentation
|
||||
* (http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/str2et_c.html)
|
||||
* \param time The time to be set as a date string
|
||||
* \param requireJump Whether or not the time change is big enough to require a
|
||||
* time-jump; defaults to true as most calls to set time will require recomputation of
|
||||
* planetary paths etc.
|
||||
*/
|
||||
void setTime(std::string time, bool requireJump = true);
|
||||
void setTime(std::string time);
|
||||
|
||||
/**
|
||||
* Returns the current time as the number of seconds past the J2000 epoch. If the
|
||||
@@ -126,39 +120,6 @@ public:
|
||||
*/
|
||||
std::string ISO8601() const;
|
||||
|
||||
/**
|
||||
* Sets the delta time value that is the number of seconds that should pass for each
|
||||
* real-time second. This value is used in the advanceTime(double) method to easily
|
||||
* advance the simulation time.
|
||||
* \param deltaT The number of seconds that should pass for each real-time second
|
||||
*/
|
||||
void setDeltaTime(double deltaT);
|
||||
|
||||
/**
|
||||
* Returns the delta time, that is the number of seconds that pass in the simulation
|
||||
* for each real-time second
|
||||
* \return The number of seconds that pass for each real-time second
|
||||
*/
|
||||
double deltaTime() const;
|
||||
|
||||
/**
|
||||
* Sets the pause function, i.e. setting the deltaTime to 0 (<code>pause</code> =
|
||||
* <code>true</code>) and restoring it when the function is called with a parameter of
|
||||
* <code>false</code>.
|
||||
* \param pause If <code>true</code>, the simulation time stops;
|
||||
* if <code>false</code>, the simulation time continues at the previous rate
|
||||
*/
|
||||
void setPause(bool pause);
|
||||
|
||||
/**
|
||||
* Toggles the pause function, i.e. setting the deltaTime to 0 and restoring it when
|
||||
* the function is called a second time. It returns the pause state (<code>true</code>
|
||||
* if the time is now paused, <code>false</code> otherwise)
|
||||
* \return The new pause state (<code>true</code> if the time is now paused,
|
||||
* <code>false</code> otherwise)
|
||||
*/
|
||||
bool togglePause();
|
||||
|
||||
/**
|
||||
* Advances the simulation time using the deltaTime() and the <code>tickTime</code>.
|
||||
* The deltaTime() is the number of simulation seconds that pass for each real-time
|
||||
@@ -171,30 +132,16 @@ public:
|
||||
*/
|
||||
double advanceTime(double tickTime);
|
||||
|
||||
bool timeJumped() const;
|
||||
|
||||
void setTimeJumped(bool jumped);
|
||||
|
||||
bool paused() const;
|
||||
|
||||
/**
|
||||
* Returns the Lua library that contains all Lua functions available to change the
|
||||
* current time, retrieve the current time etc. The functions contained are
|
||||
* - openspace::luascriptfunctions::time_setDeltaTime
|
||||
* - openspace::luascriptfunctions::time_deltaTime
|
||||
* - openspace::luascriptfunctions::time_setTime
|
||||
* - openspace::luascriptfunctions::time_currentTime
|
||||
* - openspace::luascriptfunctions::time_currentTimeUTC
|
||||
* current time, retrieve the current time etc.
|
||||
* \return The Lua library that contains all Lua functions available to change the
|
||||
* Time singleton
|
||||
* time
|
||||
*/
|
||||
static scripting::LuaLibrary luaLibrary();
|
||||
|
||||
private:
|
||||
double _time;
|
||||
double _dt = 1.0;
|
||||
bool _timeJumped = false;
|
||||
bool _timePaused = false;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -32,41 +32,112 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <deque>
|
||||
#include <functional>
|
||||
#include <openspace/util/timeline.h>
|
||||
#include <openspace/util/time.h>
|
||||
#include <openspace/util/syncdata.h>
|
||||
#include <openspace/properties/propertyowner.h>
|
||||
#include <openspace/properties/scalar/floatproperty.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class TimeManager {
|
||||
struct TimeKeyframeData {
|
||||
Time time;
|
||||
double delta;
|
||||
bool pause = false;
|
||||
bool jump = false;
|
||||
};
|
||||
|
||||
class TimeManager : public properties::PropertyOwner {
|
||||
public:
|
||||
TimeManager();
|
||||
|
||||
using CallbackHandle = int;
|
||||
using TimeChangeCallback = std::function<void()>;
|
||||
|
||||
Time& time();
|
||||
const Time& time() const;
|
||||
const Time& integrateFromTime() const;
|
||||
const Timeline<TimeKeyframeData>& timeline();
|
||||
|
||||
std::vector<Syncable*> getSyncables();
|
||||
void preSynchronization(double dt);
|
||||
void addKeyframe(double timestamp, Time keyframeTime);
|
||||
void removeKeyframesBefore(double timestamp);
|
||||
void removeKeyframesAfter(double timestamp);
|
||||
void clearKeyframes();
|
||||
|
||||
TimeKeyframeData interpolate(double applicationTime);
|
||||
|
||||
void setTimeNextFrame(Time t);
|
||||
void setDeltaTime(double deltaTime);
|
||||
void setPause(bool pause);
|
||||
|
||||
/**
|
||||
* Returns the delta time, unaffected by pause
|
||||
*/
|
||||
double targetDeltaTime() const;
|
||||
|
||||
/*
|
||||
* Returns the current delta time, as affected by pause
|
||||
*/
|
||||
double deltaTime() const;
|
||||
bool isPaused() const;
|
||||
|
||||
float defaultTimeInterpolationDuration() const;
|
||||
float defaultDeltaTimeInterpolationDuration() const;
|
||||
float defaultPauseInterpolationDuration() const;
|
||||
float defaultUnpauseInterpolationDuration() const;
|
||||
|
||||
void interpolateTime(double targetTime, double durationSeconds);
|
||||
void interpolateDeltaTime(double targetDeltaTime, double durationSeconds);
|
||||
void interpolatePause(bool pause, double durationSeconds);
|
||||
|
||||
void addKeyframe(double timestamp, TimeKeyframeData kf);
|
||||
void removeKeyframesBefore(double timestamp, bool inclusive = false);
|
||||
void removeKeyframesAfter(double timestamp, bool inclusive = false);
|
||||
|
||||
size_t nKeyframes() const;
|
||||
void clearKeyframes();
|
||||
|
||||
CallbackHandle addTimeChangeCallback(TimeChangeCallback cb);
|
||||
CallbackHandle addDeltaTimeChangeCallback(TimeChangeCallback cb);
|
||||
CallbackHandle addTimeJumpCallback(TimeChangeCallback cb);
|
||||
CallbackHandle addTimelineChangeCallback(TimeChangeCallback cb);
|
||||
|
||||
void removeTimeChangeCallback(CallbackHandle handle);
|
||||
void removeDeltaTimeChangeCallback(CallbackHandle handle);
|
||||
|
||||
void removeTimeJumpCallback(CallbackHandle handle);
|
||||
void removeTimelineChangeCallback(CallbackHandle handle);
|
||||
private:
|
||||
void progressTime(double dt);
|
||||
void applyKeyframeData(const TimeKeyframeData& keyframe);
|
||||
TimeKeyframeData interpolate(const Keyframe<TimeKeyframeData>& past,
|
||||
const Keyframe<TimeKeyframeData>& future, double time);
|
||||
|
||||
Timeline<TimeKeyframeData> _timeline;
|
||||
SyncData<Time> _currentTime;
|
||||
SyncData<Time> _integrateFromTime;
|
||||
|
||||
bool _timePaused = false;
|
||||
double _targetDeltaTime = 1.0;
|
||||
double _deltaTime = 0.0;
|
||||
double _lastTime = 0;
|
||||
double _lastDeltaTime = 0;
|
||||
|
||||
properties::FloatProperty _defaultTimeInterpolationDuration;
|
||||
properties::FloatProperty _defaultDeltaTimeInterpolationDuration;
|
||||
properties::FloatProperty _defaultPauseInterpolationDuration;
|
||||
properties::FloatProperty _defaultUnpauseInterpolationDuration;
|
||||
|
||||
bool _shouldSetTime = false;
|
||||
Time _timeNextFrame;
|
||||
Timeline<Time> _timeline;
|
||||
SyncData<Time> _currentTime;
|
||||
void consumeKeyframes(double dt);
|
||||
|
||||
bool _timelineChanged;
|
||||
|
||||
double _latestConsumedTimestamp = -std::numeric_limits<double>::max();
|
||||
int _nextCallbackHandle = 0;
|
||||
|
||||
std::vector<std::pair<CallbackHandle, TimeChangeCallback>> _timeChangeCallbacks;
|
||||
std::vector<std::pair<CallbackHandle, TimeChangeCallback>> _deltaTimeChangeCallbacks;
|
||||
double _lastTime = 0;
|
||||
double _lastDeltaTime = 0;
|
||||
std::vector<std::pair<CallbackHandle, TimeChangeCallback>> _timeJumpCallbacks;
|
||||
std::vector<std::pair<CallbackHandle, TimeChangeCallback>> _timelineChangeCallbacks;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -45,6 +45,7 @@ struct TransformData {
|
||||
struct UpdateData {
|
||||
TransformData modelTransform;
|
||||
const Time time;
|
||||
const Time previousFrameTime;
|
||||
const bool doPerformanceMeasurement;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user