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:
Emil Axelsson
2018-07-13 11:07:35 +02:00
committed by GitHub
parent 6007f1d70d
commit 902e3e6dac
42 changed files with 1465 additions and 586 deletions
+69 -72
View File
@@ -34,7 +34,7 @@ namespace openspace::datamessagestructures {
enum class Type : uint32_t {
CameraData = 0,
TimeData,
TimelineData,
ScriptData
};
@@ -52,26 +52,27 @@ struct CameraKeyframe {
double _timestamp;
void serialize(std::vector<char> &buffer) {
void serialize(std::vector<char> &buffer) const {
// Add position
buffer.insert(
buffer.end(),
reinterpret_cast<char*>(&_position),
reinterpret_cast<char*>(&_position) + sizeof(_position)
reinterpret_cast<const char*>(&_position),
reinterpret_cast<const char*>(&_position) + sizeof(_position)
);
// Add orientation
buffer.insert(
buffer.end(),
reinterpret_cast<char*>(&_rotation),
reinterpret_cast<char*>(&_rotation) + sizeof(_rotation)
reinterpret_cast<const char*>(&_rotation),
reinterpret_cast<const char*>(&_rotation) + sizeof(_rotation)
);
// Follow focus node rotation?
buffer.insert(
buffer.end(),
reinterpret_cast<char*>(&_followNodeRotation),
reinterpret_cast<char*>(&_followNodeRotation) + sizeof(_followNodeRotation)
reinterpret_cast<const char*>(&_followNodeRotation),
reinterpret_cast<const char*>(&_followNodeRotation) +
sizeof(_followNodeRotation)
);
int nodeNameLength = static_cast<int>(_focusNode.size());
@@ -79,8 +80,8 @@ struct CameraKeyframe {
// Add focus node
buffer.insert(
buffer.end(),
reinterpret_cast<char*>(&nodeNameLength),
reinterpret_cast<char*>(&nodeNameLength) + sizeof(nodeNameLength)
reinterpret_cast<const char*>(&nodeNameLength),
reinterpret_cast<const char*>(&nodeNameLength) + sizeof(nodeNameLength)
);
buffer.insert(
buffer.end(),
@@ -90,20 +91,19 @@ struct CameraKeyframe {
buffer.insert(
buffer.end(),
reinterpret_cast<char*>(&_scale),
reinterpret_cast<char*>(&_scale) + sizeof(_scale)
reinterpret_cast<const char*>(&_scale),
reinterpret_cast<const char*>(&_scale) + sizeof(_scale)
);
// Add timestamp
buffer.insert(
buffer.end(),
reinterpret_cast<char*>(&_timestamp),
reinterpret_cast<char*>(&_timestamp) + sizeof(_timestamp)
reinterpret_cast<const char*>(&_timestamp),
reinterpret_cast<const char*>(&_timestamp) + sizeof(_timestamp)
);
};
void deserialize(const std::vector<char> &buffer) {
int offset = 0;
size_t deserialize(const std::vector<char> &buffer, size_t offset = 0) {
int size = 0;
// Position
@@ -138,6 +138,9 @@ struct CameraKeyframe {
// Timestamp
size = sizeof(_timestamp);
memcpy(&_timestamp, buffer.data() + offset, size);
offset += size;
return offset;
};
};
@@ -153,71 +156,65 @@ struct TimeKeyframe {
bool _requiresTimeJump;
double _timestamp;
void serialize(std::vector<char> &buffer){
// Add current time
void serialize(std::vector<char> &buffer) const {
buffer.insert(
buffer.end(),
reinterpret_cast<char*>(&_time),
reinterpret_cast<char*>(&_time) + sizeof(_time)
);
// Add delta time
buffer.insert(
buffer.end(),
reinterpret_cast<char*>(&_dt),
reinterpret_cast<char*>(&_dt) + sizeof(_dt)
);
// Add whether time is paused or not
buffer.insert(
buffer.end(),
reinterpret_cast<char*>(&_paused),
reinterpret_cast<char*>(&_paused) + sizeof(_paused)
);
// Add whether a time jump is necessary (recompute paths etc)
buffer.insert(
buffer.end(),
reinterpret_cast<char*>(&_requiresTimeJump),
reinterpret_cast<char*>(&_requiresTimeJump) + sizeof(_requiresTimeJump)
);
// Add timestamp
buffer.insert(
buffer.end(),
reinterpret_cast<char*>(&_timestamp),
reinterpret_cast<char*>(&_timestamp) + sizeof(_timestamp)
reinterpret_cast<const char*>(this),
reinterpret_cast<const char*>(this) + sizeof(TimeKeyframe)
);
};
void deserialize(const std::vector<char> &buffer){
int offset = 0;
size_t deserialize(const std::vector<char> &buffer, size_t offset = 0){
*this = *reinterpret_cast<const TimeKeyframe*>(buffer.data() + offset);
offset += sizeof(TimeKeyframe);
return offset;
};
};
struct TimeTimeline {
TimeTimeline() {}
TimeTimeline(const std::vector<char> &buffer) {
deserialize(buffer);
}
bool _clear = true;
std::vector<TimeKeyframe> _keyframes;
void serialize(std::vector<char> &buffer) const {
buffer.insert(
buffer.end(),
reinterpret_cast<const char*>(&_clear),
reinterpret_cast<const char*>(&_clear) + sizeof(bool)
);
int64_t nKeyframes = _keyframes.size();
buffer.insert(
buffer.end(),
reinterpret_cast<const char*>(&nKeyframes),
reinterpret_cast<const char*>(&nKeyframes) + sizeof(int64_t)
);
for (const auto k : _keyframes) {
k.serialize(buffer);
}
};
size_t deserialize(const std::vector<char> &buffer, size_t offset = 0) {
int size = 0;
// Current time
size = sizeof(_time);
memcpy(&_time, buffer.data() + offset, size);
size = sizeof(_clear);
memcpy(&_clear, buffer.data() + offset, size);
offset += size;
// Delta time
size = sizeof(_dt);
memcpy(&_dt, buffer.data() + offset, size);
int64_t nKeyframes = _keyframes.size();
size = sizeof(nKeyframes);
memcpy(&nKeyframes, buffer.data() + offset, size);
offset += size;
// Is time paused?
size = sizeof(_paused);
memcpy(&_paused, buffer.data() + offset, size);
offset += sizeof(_paused);
// Is a time jump required?
size = sizeof(_requiresTimeJump);
memcpy(&_requiresTimeJump, buffer.data() + offset, size);
offset += size;
// Timestamp
size = sizeof(_timestamp);
memcpy(&_timestamp, buffer.data() + offset, size);
// offset += size;
_keyframes.resize(nKeyframes);
for (auto& k : _keyframes) {
offset = k.deserialize(buffer, offset);
}
return offset;
};
};
@@ -229,11 +226,11 @@ struct ScriptMessage {
std::string _script;
void serialize(std::vector<char> &buffer){
void serialize(std::vector<char> &buffer) const {
buffer.insert(buffer.end(), _script.begin(), _script.end());
};
void deserialize(const std::vector<char> &buffer){
void deserialize(const std::vector<char> &buffer) {
_script.assign(buffer.begin(), buffer.end());
};
};
@@ -62,9 +62,10 @@ public:
struct DataMessage {
DataMessage() = default;
DataMessage(datamessagestructures::Type t, std::vector<char> c);
DataMessage(datamessagestructures::Type t, double timestamp, std::vector<char> c);
datamessagestructures::Type type;
double timestamp;
std::vector<char> content;
};
@@ -83,6 +84,7 @@ public:
ParallelConnection::Message receiveMessage();
static const unsigned int ProtocolVersion;
private:
std::unique_ptr<ghoul::io::TcpSocket> _socket;
};
+14 -5
View File
@@ -25,6 +25,10 @@
#ifndef __OPENSPACE_CORE___PARALLELPEER___H__
#define __OPENSPACE_CORE___PARALLELPEER___H__
#include <openspace/network/parallelconnection.h>
#include <openspace/network/messagestructures.h>
#include <openspace/util/timemanager.h>
#include <openspace/properties/propertyowner.h>
#include <openspace/network/parallelconnection.h>
@@ -62,7 +66,6 @@ public:
void sendScript(std::string script);
void resetTimeOffset();
double latencyStandardDeviation() const;
double timeTolerance() const;
/**
* Returns the Lua library that contains all Lua functions available to affect the
@@ -85,24 +88,26 @@ private:
void nConnectionsMessageReceived(const std::vector<char>& message);
void sendCameraKeyframe();
void sendTimeKeyframe();
void sendTimeTimeline();
void setStatus(ParallelConnection::Status status);
void setHostName(const std::string& hostName);
void setNConnections(size_t nConnections);
double calculateBufferedKeyframeTime(double originalTime);
double convertTimestamp(double originalTime);
void analyzeTimeDifference(double messageTimestamp);
properties::StringProperty _password;
properties::StringProperty _hostPassword;
// Change to properties::IntProperty ? ---abock
// While the port should in theory be an int,
// we use a StringProperty to avoid a slider in the GUI.
properties::StringProperty _port;
properties::StringProperty _address;
properties::StringProperty _name;
properties::FloatProperty _bufferTime;
properties::FloatProperty _timeKeyframeInterval;
properties::FloatProperty _cameraKeyframeInterval;
properties::FloatProperty _timeTolerance;
double _lastTimeKeyframeTimestamp = 0.0;
double _lastCameraKeyframeTimestamp = 0.0;
@@ -119,6 +124,7 @@ private:
std::mutex _receiveBufferMutex;
std::atomic<bool> _timeJumped;
std::atomic<bool> _timeTimelineChanged;
std::mutex _latencyMutex;
std::deque<double> _latencyDiffs;
double _initialTimeDiff;
@@ -127,6 +133,9 @@ private:
std::shared_ptr<ghoul::Event<>> _connectionEvent;
ParallelConnection _connection;
TimeManager::CallbackHandle _timeJumpCallback = -1;
TimeManager::CallbackHandle _timeTimelineChangeCallback = -1;
};
} // namespace openspace