mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-05-06 03:19:17 -05:00
First steps on session recording conversion
This commit is contained in:
@@ -33,9 +33,13 @@
|
||||
|
||||
namespace openspace::interaction {
|
||||
|
||||
struct ConversionError : public ghoul::RuntimeError {
|
||||
explicit ConversionError(std::string msg);
|
||||
};
|
||||
|
||||
class SessionRecording : public properties::PropertyOwner {
|
||||
public:
|
||||
|
||||
inline static const std::string FileHeaderTitle = "OpenSpace_record/playback";
|
||||
inline static const std::string HeaderCameraAscii = "camera";
|
||||
inline static const std::string HeaderTimeAscii = "time";
|
||||
@@ -66,19 +70,18 @@ public:
|
||||
};
|
||||
|
||||
static const size_t FileHeaderVersionLength = 5;
|
||||
static constexpr char FileHeaderVersion[FileHeaderVersionLength] = {
|
||||
'0', '0', '.', '8', '5'
|
||||
};
|
||||
static constexpr char FileHeaderVersion[] = "00.85";
|
||||
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;
|
||||
static const size_t saveBufferStringSize_max = 1000;
|
||||
static const size_t _saveBufferMaxSize_bytes = keyframeHeaderSize_bytes +
|
||||
+ saveBufferCameraSize_min + saveBufferStringSize_max;
|
||||
|
||||
using CallbackHandle = int;
|
||||
using StateChangeCallback = std::function<void()>;
|
||||
SessionRecording* legacyVersion;
|
||||
|
||||
SessionRecording();
|
||||
|
||||
@@ -254,8 +257,10 @@ public:
|
||||
* \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
|
||||
*
|
||||
* \return true if data read has no errors
|
||||
*/
|
||||
static void readCameraKeyframeBinary(Timestamps& times,
|
||||
static bool readCameraKeyframeBinary(Timestamps& times,
|
||||
datamessagestructures::CameraKeyframe& kf, std::ifstream& file, int lineN);
|
||||
|
||||
/**
|
||||
@@ -266,8 +271,10 @@ public:
|
||||
* \param kf reference to a camera keyframe which contains camera details
|
||||
* \param currentParsingLine string containing the most current line that was read
|
||||
* \param lineN line number in playback file where this keyframe resides
|
||||
*
|
||||
* \return true if data read has no errors
|
||||
*/
|
||||
static void readCameraKeyframeAscii(Timestamps& times,
|
||||
static bool readCameraKeyframeAscii(Timestamps& times,
|
||||
datamessagestructures::CameraKeyframe& kf, std::string currentParsingLine,
|
||||
int lineN);
|
||||
|
||||
@@ -279,8 +286,10 @@ public:
|
||||
* \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
|
||||
*
|
||||
* \return true if data read has no errors
|
||||
*/
|
||||
static void readTimeKeyframeBinary(Timestamps& times,
|
||||
static bool readTimeKeyframeBinary(Timestamps& times,
|
||||
datamessagestructures::TimeKeyframe& kf, std::ifstream& file, int lineN);
|
||||
|
||||
/**
|
||||
@@ -291,8 +300,10 @@ public:
|
||||
* \param kf reference to a time keyframe which contains time details
|
||||
* \param currentParsingLine string containing the most current line that was read
|
||||
* \param lineN line number in playback file where this keyframe resides
|
||||
*
|
||||
* \return true if data read has no errors
|
||||
*/
|
||||
static void readTimeKeyframeAscii(Timestamps& times,
|
||||
static bool readTimeKeyframeAscii(Timestamps& times,
|
||||
datamessagestructures::TimeKeyframe& kf, std::string currentParsingLine,
|
||||
int lineN);
|
||||
|
||||
@@ -305,8 +316,10 @@ public:
|
||||
* (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
|
||||
*
|
||||
* \return true if data read has no errors
|
||||
*/
|
||||
static void readScriptKeyframeBinary(Timestamps& times,
|
||||
static bool readScriptKeyframeBinary(Timestamps& times,
|
||||
datamessagestructures::ScriptMessage& kf, std::ifstream& file, int lineN);
|
||||
|
||||
/**
|
||||
@@ -318,8 +331,10 @@ public:
|
||||
* (in chars) and the text itself
|
||||
* \param currentParsingLine string containing the most current line that was read
|
||||
* \param lineN line number in playback file where this keyframe resides
|
||||
*
|
||||
* \return true if data read has no errors
|
||||
*/
|
||||
static void readScriptKeyframeAscii(Timestamps& times,
|
||||
static bool readScriptKeyframeAscii(Timestamps& times,
|
||||
datamessagestructures::ScriptMessage& kf, std::string currentParsingLine,
|
||||
int lineN);
|
||||
|
||||
@@ -331,7 +346,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 saveCameraKeyframeBinary(Timestamps times,
|
||||
static void saveCameraKeyframeBinary(Timestamps& times,
|
||||
datamessagestructures::CameraKeyframe& kf, unsigned char* kfBuffer,
|
||||
std::ofstream& file);
|
||||
|
||||
@@ -342,7 +357,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 saveCameraKeyframeAscii(Timestamps times,
|
||||
static void saveCameraKeyframeAscii(Timestamps& times,
|
||||
datamessagestructures::CameraKeyframe& kf, std::ofstream& file);
|
||||
|
||||
/**
|
||||
@@ -353,7 +368,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 saveTimeKeyframeBinary(Timestamps times,
|
||||
static void saveTimeKeyframeBinary(Timestamps& times,
|
||||
datamessagestructures::TimeKeyframe& kf, unsigned char* kfBuffer,
|
||||
std::ofstream& file);
|
||||
|
||||
@@ -364,7 +379,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 saveTimeKeyframeAscii(Timestamps times,
|
||||
static void saveTimeKeyframeAscii(Timestamps& times,
|
||||
datamessagestructures::TimeKeyframe& kf, std::ofstream& file);
|
||||
|
||||
/**
|
||||
@@ -375,7 +390,7 @@ 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 saveScriptKeyframeBinary(Timestamps times,
|
||||
static void saveScriptKeyframeBinary(Timestamps& times,
|
||||
datamessagestructures::ScriptMessage& sm, unsigned char* smBuffer,
|
||||
std::ofstream& file);
|
||||
|
||||
@@ -386,7 +401,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 saveScriptKeyframeAscii(Timestamps times,
|
||||
static void saveScriptKeyframeAscii(Timestamps& times,
|
||||
datamessagestructures::ScriptMessage& sm, std::ofstream& file);
|
||||
|
||||
/**
|
||||
@@ -406,7 +421,7 @@ public:
|
||||
* \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,
|
||||
static void saveHeaderBinary(Timestamps& times, char type, unsigned char* kfBuffer,
|
||||
size_t& idx);
|
||||
|
||||
/**
|
||||
@@ -416,7 +431,7 @@ public:
|
||||
* \param type string signifying the keyframe type
|
||||
* \param line the stringstream buffer being written to
|
||||
*/
|
||||
static void saveHeaderAscii(Timestamps times, const std::string& type,
|
||||
static void saveHeaderAscii(Timestamps& times, const std::string& type,
|
||||
std::stringstream& line);
|
||||
|
||||
/**
|
||||
@@ -435,6 +450,14 @@ public:
|
||||
*/
|
||||
static bool hasFileExtension(std::string filename, std::string extension);
|
||||
|
||||
/**
|
||||
* Converts file format of a session recording file to the current format version
|
||||
* (will determine the file format conversion to convert from based on the file's
|
||||
* header version number).
|
||||
*
|
||||
*/
|
||||
static bool convertFile(std::string filename);
|
||||
|
||||
private:
|
||||
properties::BoolProperty _renderPlaybackInformation;
|
||||
|
||||
@@ -485,7 +508,21 @@ private:
|
||||
bool findNextFutureCameraIndex(double currTime);
|
||||
bool processCameraKeyframe(double now);
|
||||
bool processScriptKeyframe();
|
||||
//bool isDataModeBinary();
|
||||
static bool readSingleKeyframeCamera(datamessagestructures::CameraKeyframe& kf,
|
||||
Timestamps& times, DataMode mode, std::ifstream& file, std::string& inLine,
|
||||
const int lineNum);
|
||||
static void saveSingleKeyframeCamera(datamessagestructures::CameraKeyframe& kf,
|
||||
Timestamps& times, DataMode mode, std::ofstream& file, unsigned char* buffer);
|
||||
static bool readSingleKeyframeTime(datamessagestructures::TimeKeyframe& kf,
|
||||
Timestamps& times, DataMode mode, std::ifstream& file, std::string& inLine,
|
||||
const int lineNum);
|
||||
static void saveSingleKeyframeTime(datamessagestructures::TimeKeyframe& kf,
|
||||
Timestamps& times, DataMode mode, std::ofstream& file, unsigned char* buffer);
|
||||
static bool readSingleKeyframeScript(datamessagestructures::ScriptMessage& kf,
|
||||
Timestamps& times, DataMode mode, std::ifstream& file, std::string& inLine,
|
||||
const int lineNum);
|
||||
static void saveSingleKeyframeScript(datamessagestructures::ScriptMessage& kf,
|
||||
Timestamps& times, DataMode mode, std::ofstream& file, unsigned char* buffer);
|
||||
unsigned int findIndexOfLastCameraKeyframeInTimeline();
|
||||
bool doesTimelineEntryContainCamera(unsigned int index) const;
|
||||
std::vector<std::pair<CallbackHandle, StateChangeCallback>> _stateChangeCallbacks;
|
||||
@@ -495,6 +532,15 @@ private:
|
||||
double getNextTimestamp();
|
||||
double getPrevTimestamp();
|
||||
void cleanUpPlayback();
|
||||
static bool convertEntries(std::string& inFilename, std::ifstream& inFile,
|
||||
DataMode mode, int lineNum, std::ofstream& outFile);
|
||||
static bool convertCamera(std::ifstream& inFile, DataMode mode, int lineNum,
|
||||
std::string& inputLine, std::ofstream& outFile, unsigned char* buff);
|
||||
static bool convertTimeChange(std::ifstream& inFile, DataMode mode, int lineNum,
|
||||
std::string& inputLine, std::ofstream& outFile, unsigned char* buff);
|
||||
static bool convertScript(std::ifstream& inFile, DataMode mode, int lineNum,
|
||||
std::string& inputLine, std::ofstream& outFile, unsigned char* buff);
|
||||
static std::string determineConversionOutFilename(const std::string filename);
|
||||
|
||||
static void writeToFileBuffer(unsigned char* buf, size_t& idx, double src);
|
||||
static void writeToFileBuffer(unsigned char* buf, size_t& idx, std::vector<char>& cv);
|
||||
@@ -541,6 +587,30 @@ private:
|
||||
double _cameraFirstInTimeline_timestamp = 0;
|
||||
|
||||
int _nextCallbackHandle = 0;
|
||||
|
||||
DataMode _conversionDataMode = DataMode::Binary;
|
||||
int _conversionLineNum = 1;
|
||||
};
|
||||
|
||||
class SessionRecording_legacy_0085 : SessionRecording {
|
||||
struct ScriptMessage_legacy_0085 : datamessagestructures::ScriptMessage {
|
||||
void read(std::istream* in) {
|
||||
size_t strLen;
|
||||
//Read string length from file
|
||||
in->read(reinterpret_cast<char*>(&strLen), sizeof(strLen));
|
||||
//Read back full string
|
||||
std::vector<char> temp(strLen + 1);
|
||||
in->read(temp.data(), strLen);
|
||||
temp[strLen] = '\0';
|
||||
|
||||
_script.erase();
|
||||
_script = temp.data();
|
||||
};
|
||||
};
|
||||
|
||||
void convertUp(std::string header, std::string fileToConvert);
|
||||
|
||||
static constexpr char FileHeaderVersion[] = "01.00";
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -370,6 +370,7 @@ struct ScriptMessage {
|
||||
ScriptMessage(const std::vector<char>& buffer) {
|
||||
deserialize(buffer);
|
||||
}
|
||||
virtual ~ScriptMessage() {};
|
||||
|
||||
std::string _script;
|
||||
double _timestamp = 0.0;
|
||||
@@ -429,8 +430,8 @@ struct ScriptMessage {
|
||||
ss << _script;
|
||||
}
|
||||
|
||||
void read(std::istream* in) {
|
||||
size_t strLen;
|
||||
virtual void read(std::istream* in) {
|
||||
uint32_t strLen;
|
||||
//Read string length from file
|
||||
in->read(reinterpret_cast<char*>(&strLen), sizeof(strLen));
|
||||
//Read back full string
|
||||
|
||||
@@ -265,7 +265,8 @@ bool SessionRecording::startPlayback(const std::string& filename,
|
||||
size_t headerSize = FileHeaderTitle.length() +
|
||||
FileHeaderVersionLength +
|
||||
sizeof(DataFormatBinaryTag) + sizeof('\n');
|
||||
_playbackFile.read(reinterpret_cast<char*>(&_keyframeBuffer), headerSize);
|
||||
char hBuffer[headerSize];
|
||||
_playbackFile.read(reinterpret_cast<char*>(hBuffer), headerSize);
|
||||
}
|
||||
|
||||
if (!_playbackFile.is_open() || !_playbackFile.good()) {
|
||||
@@ -500,15 +501,10 @@ void SessionRecording::saveCameraKeyframe() {
|
||||
kf._timestamp - _timestampRecordStarted,
|
||||
global::timeManager.time().j2000Seconds()
|
||||
};
|
||||
if (_recordingDataMode == DataMode::Binary) {
|
||||
saveCameraKeyframeBinary(times, kf, _keyframeBuffer, _recordFile);
|
||||
}
|
||||
else {
|
||||
saveCameraKeyframeAscii(times, kf, _recordFile);
|
||||
}
|
||||
saveSingleKeyframeCamera(kf, times, _recordingDataMode, _recordFile, _keyframeBuffer);
|
||||
}
|
||||
|
||||
void SessionRecording::saveHeaderBinary(Timestamps times,
|
||||
void SessionRecording::saveHeaderBinary(Timestamps& times,
|
||||
char type,
|
||||
unsigned char* kfBuffer,
|
||||
size_t& idx)
|
||||
@@ -519,7 +515,7 @@ void SessionRecording::saveHeaderBinary(Timestamps times,
|
||||
writeToFileBuffer(kfBuffer, idx, times.timeSim);
|
||||
}
|
||||
|
||||
void SessionRecording::saveHeaderAscii(Timestamps times,
|
||||
void SessionRecording::saveHeaderAscii(Timestamps& times,
|
||||
const std::string& type,
|
||||
std::stringstream& line)
|
||||
{
|
||||
@@ -529,7 +525,7 @@ void SessionRecording::saveHeaderAscii(Timestamps times,
|
||||
line << std::fixed << std::setprecision(3) << times.timeSim << ' ';
|
||||
}
|
||||
|
||||
void SessionRecording::saveCameraKeyframeBinary(Timestamps times,
|
||||
void SessionRecording::saveCameraKeyframeBinary(Timestamps& times,
|
||||
datamessagestructures::CameraKeyframe& kf,
|
||||
unsigned char* kfBuffer,
|
||||
std::ofstream& file)
|
||||
@@ -544,7 +540,7 @@ void SessionRecording::saveCameraKeyframeBinary(Timestamps times,
|
||||
saveKeyframeToFileBinary(kfBuffer, idx, file);
|
||||
}
|
||||
|
||||
void SessionRecording::saveCameraKeyframeAscii(Timestamps times,
|
||||
void SessionRecording::saveCameraKeyframeAscii(Timestamps& times,
|
||||
datamessagestructures::CameraKeyframe& kf,
|
||||
std::ofstream& file)
|
||||
{
|
||||
@@ -567,14 +563,10 @@ void SessionRecording::saveTimeKeyframe() {
|
||||
kf._timestamp - _timestampRecordStarted,
|
||||
global::timeManager.time().j2000Seconds()
|
||||
};
|
||||
if (_recordingDataMode == DataMode::Binary) {
|
||||
saveTimeKeyframeBinary(times, kf, _keyframeBuffer, _recordFile);
|
||||
} else {
|
||||
saveTimeKeyframeAscii(times, kf, _recordFile);
|
||||
}
|
||||
saveSingleKeyframeTime(kf, times, _recordingDataMode, _recordFile, _keyframeBuffer);
|
||||
}
|
||||
|
||||
void SessionRecording::saveTimeKeyframeBinary(Timestamps times,
|
||||
void SessionRecording::saveTimeKeyframeBinary(Timestamps& times,
|
||||
datamessagestructures::TimeKeyframe& kf,
|
||||
unsigned char* kfBuffer,
|
||||
std::ofstream& file)
|
||||
@@ -587,7 +579,7 @@ void SessionRecording::saveTimeKeyframeBinary(Timestamps times,
|
||||
saveKeyframeToFileBinary(kfBuffer, idx, file);
|
||||
}
|
||||
|
||||
void SessionRecording::saveTimeKeyframeAscii(Timestamps times,
|
||||
void SessionRecording::saveTimeKeyframeAscii(Timestamps& times,
|
||||
datamessagestructures::TimeKeyframe& kf,
|
||||
std::ofstream& file)
|
||||
{
|
||||
@@ -597,7 +589,8 @@ void SessionRecording::saveTimeKeyframeAscii(Timestamps times,
|
||||
saveKeyframeToFile(keyframeLine.str(), file);
|
||||
}
|
||||
|
||||
void SessionRecording::saveScriptKeyframe(std::string scriptToSave) {
|
||||
void SessionRecording::saveScriptKeyframe(std::string scriptToSave)
|
||||
{
|
||||
if (_state != SessionState::Recording) {
|
||||
return;
|
||||
}
|
||||
@@ -611,15 +604,16 @@ void SessionRecording::saveScriptKeyframe(std::string scriptToSave) {
|
||||
global::timeManager.time().j2000Seconds()
|
||||
};
|
||||
|
||||
if (_recordingDataMode == DataMode::Binary) {
|
||||
saveScriptKeyframeBinary(times, sm, _keyframeBuffer, _recordFile);
|
||||
}
|
||||
else {
|
||||
saveScriptKeyframeAscii(times, sm, _recordFile);
|
||||
}
|
||||
saveSingleKeyframeScript(
|
||||
sm,
|
||||
times,
|
||||
_recordingDataMode,
|
||||
_recordFile,
|
||||
_keyframeBuffer
|
||||
);
|
||||
}
|
||||
|
||||
void SessionRecording::saveScriptKeyframeBinary(Timestamps times,
|
||||
void SessionRecording::saveScriptKeyframeBinary(Timestamps& times,
|
||||
datamessagestructures::ScriptMessage& sm,
|
||||
unsigned char* smBuffer,
|
||||
std::ofstream& file)
|
||||
@@ -633,7 +627,7 @@ void SessionRecording::saveScriptKeyframeBinary(Timestamps times,
|
||||
saveKeyframeToFileBinary(smBuffer, idx, file);
|
||||
}
|
||||
|
||||
void SessionRecording::saveScriptKeyframeAscii(Timestamps times,
|
||||
void SessionRecording::saveScriptKeyframeAscii(Timestamps& times,
|
||||
datamessagestructures::ScriptMessage& sm,
|
||||
std::ofstream& file)
|
||||
{
|
||||
@@ -871,12 +865,14 @@ bool SessionRecording::playbackCamera() {
|
||||
Timestamps times;
|
||||
datamessagestructures::CameraKeyframe kf;
|
||||
|
||||
if (_recordingDataMode == DataMode::Binary) {
|
||||
readCameraKeyframeBinary(times, kf, _playbackFile, _playbackLineNum);
|
||||
}
|
||||
else {
|
||||
readCameraKeyframeAscii(times, kf, _playbackLineParsing, _playbackLineNum);
|
||||
}
|
||||
bool success = readSingleKeyframeCamera(
|
||||
kf,
|
||||
times,
|
||||
_recordingDataMode,
|
||||
_playbackFile,
|
||||
_playbackLineParsing,
|
||||
_playbackLineNum
|
||||
);
|
||||
|
||||
if (_setSimulationTimeWithNextCameraKeyframe) {
|
||||
global::timeManager.setTimeNextFrame(Time(times.timeSim));
|
||||
@@ -886,10 +882,65 @@ bool SessionRecording::playbackCamera() {
|
||||
double timeRef = appropriateTimestamp(times.timeOs, times.timeRec, times.timeSim);
|
||||
|
||||
interaction::KeyframeNavigator::CameraPose pbFrame(std::move(kf));
|
||||
return addKeyframe(timeRef, pbFrame, _playbackLineNum);
|
||||
if (success) {
|
||||
success = addKeyframe(timeRef, pbFrame, _playbackLineNum);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
void SessionRecording::readCameraKeyframeBinary(Timestamps& times,
|
||||
bool SessionRecording::convertCamera(std::ifstream& inFile, DataMode mode, int lineNum,
|
||||
std::string& inputLine, std::ofstream& outFile,
|
||||
unsigned char* buffer)
|
||||
{
|
||||
Timestamps times;
|
||||
datamessagestructures::CameraKeyframe kf;
|
||||
|
||||
bool success = readSingleKeyframeCamera(
|
||||
kf,
|
||||
times,
|
||||
mode,
|
||||
inFile,
|
||||
inputLine,
|
||||
lineNum
|
||||
);
|
||||
if (success) {
|
||||
saveSingleKeyframeCamera(
|
||||
kf,
|
||||
times,
|
||||
mode,
|
||||
outFile,
|
||||
buffer
|
||||
);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
bool SessionRecording::readSingleKeyframeCamera(datamessagestructures::CameraKeyframe& kf,
|
||||
Timestamps& times, DataMode mode,
|
||||
std::ifstream& file, std::string& inLine,
|
||||
const int lineNum)
|
||||
{
|
||||
if (mode == DataMode::Binary) {
|
||||
return readCameraKeyframeBinary(times, kf, file, lineNum);
|
||||
}
|
||||
else {
|
||||
return readCameraKeyframeAscii(times, kf, inLine, lineNum);
|
||||
}
|
||||
}
|
||||
|
||||
void SessionRecording::saveSingleKeyframeCamera(datamessagestructures::CameraKeyframe& kf,
|
||||
Timestamps& times, DataMode mode,
|
||||
std::ofstream& file, unsigned char* buffer)
|
||||
{
|
||||
if (mode == DataMode::Binary) {
|
||||
saveCameraKeyframeBinary(times, kf, buffer, file);
|
||||
}
|
||||
else {
|
||||
saveCameraKeyframeAscii(times, kf, file);
|
||||
}
|
||||
}
|
||||
|
||||
bool SessionRecording::readCameraKeyframeBinary(Timestamps& times,
|
||||
datamessagestructures::CameraKeyframe& kf,
|
||||
std::ifstream& file, int lineN)
|
||||
{
|
||||
@@ -904,14 +955,14 @@ void SessionRecording::readCameraKeyframeBinary(Timestamps& times,
|
||||
"Allocation error with camera playback from keyframe entry {}",
|
||||
lineN - 1
|
||||
));
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
catch (std::length_error&) {
|
||||
LERROR(fmt::format(
|
||||
"length_error with camera playback from keyframe entry {}",
|
||||
lineN - 1
|
||||
));
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
times.timeOs = kf._timestamp;
|
||||
|
||||
@@ -920,11 +971,12 @@ void SessionRecording::readCameraKeyframeBinary(Timestamps& times,
|
||||
"Error reading camera playback from keyframe entry {}",
|
||||
lineN - 1
|
||||
));
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void SessionRecording::readCameraKeyframeAscii(Timestamps& times,
|
||||
bool SessionRecording::readCameraKeyframeAscii(Timestamps& times,
|
||||
datamessagestructures::CameraKeyframe& kf,
|
||||
std::string currentParsingLine,
|
||||
int lineN)
|
||||
@@ -941,28 +993,85 @@ void SessionRecording::readCameraKeyframeAscii(Timestamps& times,
|
||||
|
||||
if (iss.fail() || !iss.eof()) {
|
||||
LERROR(fmt::format("Error parsing camera line {} of playback file", lineN));
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SessionRecording::playbackTimeChange() {
|
||||
Timestamps times;
|
||||
datamessagestructures::TimeKeyframe kf;
|
||||
|
||||
if (_recordingDataMode == DataMode::Binary) {
|
||||
readTimeKeyframeBinary(times, kf, _playbackFile, _playbackLineNum);
|
||||
} else {
|
||||
readTimeKeyframeAscii(times, kf, _playbackLineParsing, _playbackLineNum);
|
||||
}
|
||||
bool success = readSingleKeyframeTime(
|
||||
kf,
|
||||
times,
|
||||
_recordingDataMode,
|
||||
_playbackFile,
|
||||
_playbackLineParsing,
|
||||
_playbackLineNum
|
||||
);
|
||||
kf._timestamp = equivalentApplicationTime(times.timeOs, times.timeRec, times.timeSim);
|
||||
|
||||
kf._time = kf._timestamp + _timestampApplicationStarted_simulation;
|
||||
//global::timeManager.addKeyframe(timeRef, pbFrame._timestamp);
|
||||
//_externInteract.timeInteraction(pbFrame);
|
||||
return addKeyframe(kf._timestamp, kf, _playbackLineNum);
|
||||
if (success) {
|
||||
success = addKeyframe(kf._timestamp, kf, _playbackLineNum);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
void SessionRecording::readTimeKeyframeBinary(Timestamps& times,
|
||||
bool SessionRecording::convertTimeChange(std::ifstream& inFile, DataMode mode, int lineNum,
|
||||
std::string& inputLine, std::ofstream& outFile,
|
||||
unsigned char* buffer)
|
||||
{
|
||||
Timestamps times;
|
||||
datamessagestructures::TimeKeyframe kf;
|
||||
|
||||
bool success = readSingleKeyframeTime(
|
||||
kf,
|
||||
times,
|
||||
mode,
|
||||
inFile,
|
||||
inputLine,
|
||||
lineNum
|
||||
);
|
||||
if (success) {
|
||||
saveSingleKeyframeTime(
|
||||
kf,
|
||||
times,
|
||||
mode,
|
||||
outFile,
|
||||
buffer
|
||||
);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
bool SessionRecording::readSingleKeyframeTime(datamessagestructures::TimeKeyframe& kf,
|
||||
Timestamps& times, DataMode mode,
|
||||
std::ifstream& file, std::string& inLine,
|
||||
const int lineNum)
|
||||
{
|
||||
if (mode == DataMode::Binary) {
|
||||
return readTimeKeyframeBinary(times, kf, file, lineNum);
|
||||
} else {
|
||||
return readTimeKeyframeAscii(times, kf, inLine, lineNum);
|
||||
}
|
||||
}
|
||||
|
||||
void SessionRecording::saveSingleKeyframeTime(datamessagestructures::TimeKeyframe& kf,
|
||||
Timestamps& times, DataMode mode,
|
||||
std::ofstream& file, unsigned char* buffer)
|
||||
{
|
||||
if (mode == DataMode::Binary) {
|
||||
saveTimeKeyframeBinary(times, kf, buffer, file);
|
||||
} else {
|
||||
saveTimeKeyframeAscii(times, kf, file);
|
||||
}
|
||||
}
|
||||
|
||||
bool SessionRecording::readTimeKeyframeBinary(Timestamps& times,
|
||||
datamessagestructures::TimeKeyframe& kf,
|
||||
std::ifstream& file, int lineN)
|
||||
{
|
||||
@@ -978,25 +1087,26 @@ void SessionRecording::readTimeKeyframeBinary(Timestamps& times,
|
||||
"Allocation error with time playback from keyframe entry {}",
|
||||
lineN - 1
|
||||
));
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
catch (std::length_error&) {
|
||||
LERROR(fmt::format(
|
||||
"length_error with time playback from keyframe entry {}",
|
||||
lineN - 1
|
||||
));
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!file) {
|
||||
LERROR(fmt::format(
|
||||
"Error reading time playback from keyframe entry {}", lineN - 1
|
||||
));
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void SessionRecording::readTimeKeyframeAscii(Timestamps& times,
|
||||
bool SessionRecording::readTimeKeyframeAscii(Timestamps& times,
|
||||
datamessagestructures::TimeKeyframe& kf,
|
||||
std::string currentParsingLine,
|
||||
int lineN)
|
||||
@@ -1012,8 +1122,9 @@ void SessionRecording::readTimeKeyframeAscii(Timestamps& times,
|
||||
LERROR(fmt::format(
|
||||
"Error parsing time line {} of playback file", lineN
|
||||
));
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string SessionRecording::readHeaderElement(std::ifstream& stream,
|
||||
@@ -1028,17 +1139,75 @@ bool SessionRecording::playbackScript() {
|
||||
Timestamps times;
|
||||
datamessagestructures::ScriptMessage kf;
|
||||
|
||||
if (_recordingDataMode == DataMode::Binary) {
|
||||
readScriptKeyframeBinary(times, kf, _playbackFile, _playbackLineNum);
|
||||
} else {
|
||||
readScriptKeyframeAscii(times, kf, _playbackLineParsing, _playbackLineNum);
|
||||
}
|
||||
bool success = readSingleKeyframeScript(
|
||||
kf,
|
||||
times,
|
||||
_recordingDataMode,
|
||||
_playbackFile,
|
||||
_playbackLineParsing,
|
||||
_playbackLineNum
|
||||
);
|
||||
|
||||
double timeRef = appropriateTimestamp(times.timeOs, times.timeRec, times.timeSim);
|
||||
return addKeyframe(timeRef, kf._script, _playbackLineNum);
|
||||
if (success) {
|
||||
success = addKeyframe(timeRef, kf._script, _playbackLineNum);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
void SessionRecording::readScriptKeyframeBinary(Timestamps& times,
|
||||
bool SessionRecording::convertScript(std::ifstream& inFile, DataMode mode, int lineNum,
|
||||
std::string& inputLine, std::ofstream& outFile,
|
||||
unsigned char* buffer)
|
||||
{
|
||||
Timestamps times;
|
||||
datamessagestructures::ScriptMessage kf;
|
||||
|
||||
bool success = readSingleKeyframeScript(
|
||||
kf,
|
||||
times,
|
||||
mode,
|
||||
inFile,
|
||||
inputLine,
|
||||
lineNum
|
||||
);
|
||||
if (success) {
|
||||
saveSingleKeyframeScript(
|
||||
kf,
|
||||
times,
|
||||
mode,
|
||||
outFile,
|
||||
buffer
|
||||
);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
bool SessionRecording::readSingleKeyframeScript(datamessagestructures::ScriptMessage& kf,
|
||||
Timestamps& times, DataMode mode,
|
||||
std::ifstream& file, std::string& inLine,
|
||||
const int lineNum)
|
||||
{
|
||||
if (mode == DataMode::Binary) {
|
||||
return readScriptKeyframeBinary(times, kf, file, lineNum);
|
||||
}
|
||||
else {
|
||||
return readScriptKeyframeAscii(times, kf, inLine, lineNum);
|
||||
}
|
||||
}
|
||||
|
||||
void SessionRecording::saveSingleKeyframeScript(datamessagestructures::ScriptMessage& kf,
|
||||
Timestamps& times, DataMode mode,
|
||||
std::ofstream& file, unsigned char* buffer)
|
||||
{
|
||||
if (mode == DataMode::Binary) {
|
||||
saveScriptKeyframeBinary(times, kf, buffer, file);
|
||||
}
|
||||
else {
|
||||
saveScriptKeyframeAscii(times, kf, file);
|
||||
}
|
||||
}
|
||||
|
||||
bool SessionRecording::readScriptKeyframeBinary(Timestamps& times,
|
||||
datamessagestructures::ScriptMessage& kf,
|
||||
std::ifstream& file, int lineN)
|
||||
{
|
||||
@@ -1054,14 +1223,14 @@ void SessionRecording::readScriptKeyframeBinary(Timestamps& times,
|
||||
"Allocation error with script playback from keyframe entry {}",
|
||||
lineN - 1
|
||||
));
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
catch (std::length_error&) {
|
||||
LERROR(fmt::format(
|
||||
"length_error with script playback from keyframe entry {}",
|
||||
lineN - 1
|
||||
));
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!file) {
|
||||
@@ -1069,11 +1238,12 @@ void SessionRecording::readScriptKeyframeBinary(Timestamps& times,
|
||||
"Error reading script playback from keyframe entry {}",
|
||||
lineN - 1
|
||||
));
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void SessionRecording::readScriptKeyframeAscii(Timestamps& times,
|
||||
bool SessionRecording::readScriptKeyframeAscii(Timestamps& times,
|
||||
datamessagestructures::ScriptMessage& kf,
|
||||
std::string currentParsingLine,
|
||||
int lineN)
|
||||
@@ -1087,13 +1257,14 @@ void SessionRecording::readScriptKeyframeAscii(Timestamps& times,
|
||||
LERROR(fmt::format(
|
||||
"Error parsing script line {} of playback file", lineN
|
||||
));
|
||||
return;
|
||||
return false;
|
||||
} else if (!iss.eof()) {
|
||||
LERROR(fmt::format(
|
||||
"Did not find an EOL at line {} of playback file", lineN
|
||||
));
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SessionRecording::addKeyframe(double timestamp,
|
||||
@@ -1448,7 +1619,7 @@ void SessionRecording::saveKeyframeToFileBinary(unsigned char* buffer,
|
||||
size_t size,
|
||||
std::ofstream& file)
|
||||
{
|
||||
file.write(reinterpret_cast<char*>(buffer), size);
|
||||
file.write(reinterpret_cast<unsigned char*>(buffer), size);
|
||||
}
|
||||
|
||||
void SessionRecording::saveKeyframeToFile(std::string entry, std::ofstream& file) {
|
||||
@@ -1588,4 +1759,236 @@ scripting::LuaLibrary SessionRecording::luaLibrary() {
|
||||
};
|
||||
}
|
||||
|
||||
bool SessionRecording::convertFile(std::string filename) {
|
||||
bool success = true;
|
||||
|
||||
try {
|
||||
if (filename.find("/") != std::string::npos) {
|
||||
throw ConversionError("Playback filename musn't contain path (/) elements");
|
||||
}
|
||||
std::string conversionInFilename = absPath("${RECORDINGS}/" + filename);
|
||||
if (!FileSys.fileExists(conversionInFilename)) {
|
||||
throw ConversionError("Cannot find the specified playback file to convert.");
|
||||
}
|
||||
|
||||
int conversionLineNum = 1;
|
||||
// Open in ASCII first
|
||||
std::ifstream conversionInFile;
|
||||
conversionInFile.open(conversionInFilename, std::ifstream::in);
|
||||
// Read header
|
||||
std::string readBackHeaderString = readHeaderElement(
|
||||
conversionInFile,
|
||||
FileHeaderTitle.length()
|
||||
);
|
||||
|
||||
if (readBackHeaderString != FileHeaderTitle) {
|
||||
throw ConversionError("File to convert does not contain expected header.");
|
||||
}
|
||||
if (readBackHeaderString != FileHeaderTitle) {
|
||||
throw ConversionError("File to convert does not contain expected header.");
|
||||
}
|
||||
readHeaderElement(conversionInFile, FileHeaderVersionLength);
|
||||
std::string readDataMode = readHeaderElement(conversionInFile, 1);
|
||||
DataMode mode;
|
||||
if (readDataMode[0] == DataFormatAsciiTag) {
|
||||
mode = DataMode::Ascii;
|
||||
}
|
||||
else if (readDataMode[0] == DataFormatBinaryTag) {
|
||||
mode = DataMode::Binary;
|
||||
}
|
||||
else {
|
||||
throw ConversionError("Unknown data type in header (needs Ascii or Binary)");
|
||||
}
|
||||
|
||||
if (!conversionInFile.is_open() || !conversionInFile.good()) {
|
||||
throw ConversionError(fmt::format(
|
||||
"Unable to open file {} for conversion", conversionInFilename.c_str()
|
||||
));
|
||||
}
|
||||
|
||||
std::string conversionOutFilename = determineConversionOutFilename(filename);
|
||||
std::ofstream conversionOutFile;
|
||||
if (mode == DataMode::Binary) {
|
||||
conversionOutFile.open(conversionOutFilename, std::ios::binary);
|
||||
}
|
||||
else {
|
||||
conversionOutFile.open(conversionOutFilename);
|
||||
}
|
||||
if (!conversionOutFile.is_open() || !conversionOutFile.good()) {
|
||||
LERROR(fmt::format(
|
||||
"Unable to open file {} for conversion result",
|
||||
conversionOutFilename.c_str()
|
||||
));
|
||||
return false;
|
||||
}
|
||||
|
||||
success = convertEntries(
|
||||
conversionInFilename,
|
||||
conversionInFile,
|
||||
mode,
|
||||
conversionLineNum,
|
||||
conversionOutFile
|
||||
);
|
||||
}
|
||||
catch (ConversionError& c) {
|
||||
LERROR(c.message);
|
||||
success = false;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool SessionRecording::convertEntries(std::string& inFilename, std::ifstream& inFile,
|
||||
DataMode mode, int lineNum, std::ofstream& outFile)
|
||||
{
|
||||
bool conversionStatusOk = true;
|
||||
std::string lineParsing;
|
||||
std::shared_ptr<char[]> buffer(new char[_saveBufferMaxSize_bytes]);
|
||||
|
||||
if (mode == DataMode::Binary) {
|
||||
unsigned char frameType;
|
||||
bool fileReadOk = true;
|
||||
|
||||
while (conversionStatusOk && fileReadOk) {
|
||||
frameType = readFromPlayback<unsigned char>(inFile);
|
||||
// Check if have reached EOF
|
||||
if (!inFile) {
|
||||
LINFO(fmt::format(
|
||||
"Finished converting {} entries from playback file {}",
|
||||
lineNum - 1, inFilename
|
||||
));
|
||||
fileReadOk = false;
|
||||
break;
|
||||
}
|
||||
if (frameType == HeaderCameraBinary) {
|
||||
conversionStatusOk = convertCamera(
|
||||
inFile,
|
||||
mode,
|
||||
lineNum,
|
||||
lineParsing,
|
||||
outFile,
|
||||
buffer
|
||||
);
|
||||
}
|
||||
else if (frameType == HeaderTimeBinary) {
|
||||
conversionStatusOk = convertTimeChange(
|
||||
inFile,
|
||||
mode,
|
||||
lineNum,
|
||||
lineParsing,
|
||||
outFile,
|
||||
buffer
|
||||
);
|
||||
}
|
||||
else if (frameType == HeaderScriptBinary) {
|
||||
conversionStatusOk = convertScript(
|
||||
inFile,
|
||||
mode,
|
||||
lineNum,
|
||||
lineParsing,
|
||||
outFile,
|
||||
buffer
|
||||
);
|
||||
}
|
||||
else {
|
||||
LERROR(fmt::format(
|
||||
"Unknown frame type {} @ index {} of conversion file {}",
|
||||
frameType, lineNum - 1, inFilename
|
||||
));
|
||||
conversionStatusOk = false;
|
||||
break;
|
||||
}
|
||||
lineNum++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
while (conversionStatusOk && std::getline(inFile, lineParsing)) {
|
||||
lineNum++;
|
||||
|
||||
std::istringstream iss(lineParsing);
|
||||
std::string entryType;
|
||||
if (!(iss >> entryType)) {
|
||||
LERROR(fmt::format(
|
||||
"Error reading entry type @ line {} of conversion file {}",
|
||||
lineNum, inFilename
|
||||
));
|
||||
break;
|
||||
}
|
||||
|
||||
if (entryType == HeaderCameraAscii) {
|
||||
conversionStatusOk = convertCamera(
|
||||
inFile,
|
||||
mode,
|
||||
lineNum,
|
||||
lineParsing,
|
||||
outFile,
|
||||
buffer
|
||||
);
|
||||
}
|
||||
else if (entryType == HeaderTimeAscii) {
|
||||
conversionStatusOk = convertTimeChange(
|
||||
inFile,
|
||||
mode,
|
||||
lineNum,
|
||||
lineParsing,
|
||||
outFile,
|
||||
buffer
|
||||
);
|
||||
}
|
||||
else if (entryType == HeaderScriptAscii) {
|
||||
conversionStatusOk = convertScript(
|
||||
inFile,
|
||||
mode,
|
||||
lineNum,
|
||||
lineParsing,
|
||||
outFile,
|
||||
buffer
|
||||
);
|
||||
}
|
||||
else if (entryType.substr(0, 1) == HeaderCommentAscii) {
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
LERROR(fmt::format(
|
||||
"Unknown frame type {} @ line {} of conversion file {}",
|
||||
entryType, lineNum, inFilename
|
||||
));
|
||||
conversionStatusOk = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
LINFO(fmt::format(
|
||||
"Finished parsing {} entries from conversion file {}",
|
||||
lineNum, inFilename
|
||||
));
|
||||
}
|
||||
return conversionStatusOk;
|
||||
}
|
||||
|
||||
std::string SessionRecording::determineConversionOutFilename(const std::string filename) {
|
||||
std::string conversionOutFilename;
|
||||
if (filename.substr(filename.find_last_of(".")) == FileExtensionBinary) {
|
||||
conversionOutFilename = filename.substr(0, filename.find_last_of("."))
|
||||
+ "_" + FileHeaderVersion + FileExtensionBinary;
|
||||
}
|
||||
else if (filename.substr(filename.find_last_of(".")) == FileExtensionAscii) {
|
||||
conversionOutFilename = filename.substr(0, filename.find_last_of("."))
|
||||
+ "_" + FileHeaderVersion + FileExtensionAscii;
|
||||
}
|
||||
else {
|
||||
conversionOutFilename = filename + "_";
|
||||
}
|
||||
return absPath("${RECORDINGS}/convert/" + conversionOutFilename);
|
||||
}
|
||||
|
||||
void SessionRecording_legacy_0085::convertUp(std::string header, std::string fileToConvert)
|
||||
{
|
||||
if (strcmp(legacyVersion->FileHeaderVersion, FileHeaderVersion) == 0) {
|
||||
convertFile(fileToConvert);
|
||||
}
|
||||
else {
|
||||
//Oldest known version
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace openspace::interaction
|
||||
|
||||
Reference in New Issue
Block a user