mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-02-25 06:19:02 -06:00
Conversion task working for both directions
This commit is contained in:
7
data/tasks/sessionRecordConvertExample1.task
Normal file
7
data/tasks/sessionRecordConvertExample1.task
Normal file
@@ -0,0 +1,7 @@
|
||||
return {
|
||||
{
|
||||
Type = "ConvertRecFormatTask",
|
||||
InputFilePath = "../../recordings/input",
|
||||
OutputFilePath = "../../recordings/output"
|
||||
}
|
||||
}
|
||||
@@ -32,13 +32,21 @@
|
||||
|
||||
namespace openspace::interaction {
|
||||
|
||||
enum class SessionRecordingDataMode {
|
||||
Ascii = 0,
|
||||
Binary,
|
||||
Unknown
|
||||
};
|
||||
static const std::string SessionRecordingFileHeaderTitle = "OpenSpace_record/playback";
|
||||
static const std::string SessionRecordingHeaderCameraAscii = "camera";
|
||||
static const std::string SessionRecordingHeaderTimeAscii = "time";
|
||||
static const std::string SessionRecordingHeaderScriptAscii = "script";
|
||||
static const char SessionRecordingHeaderCameraBinary = 'c';
|
||||
static const char SessionRecordingHeaderTimeBinary = 't';
|
||||
static const char SessionRecordingHeaderScriptBinary = 's';
|
||||
|
||||
class SessionRecording : public properties::PropertyOwner {
|
||||
public:
|
||||
enum class RecordedDataMode {
|
||||
Ascii = 0,
|
||||
Binary
|
||||
};
|
||||
|
||||
enum class SessionState {
|
||||
Idle = 0,
|
||||
Recording,
|
||||
@@ -51,14 +59,12 @@ public:
|
||||
double timeSim;
|
||||
};
|
||||
|
||||
const std::string FileHeaderTitle = "OpenSpace_record/playback";
|
||||
static const size_t FileHeaderVersionLength = 5;
|
||||
const char FileHeaderVersion[FileHeaderVersionLength] = {
|
||||
static constexpr char FileHeaderVersion[FileHeaderVersionLength] = {
|
||||
'0', '0', '.', '8', '5'
|
||||
};
|
||||
const char DataFormatAsciiTag = 'A';
|
||||
const char DataFormatBinaryTag = 'B';
|
||||
|
||||
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;
|
||||
@@ -114,7 +120,7 @@ public:
|
||||
*
|
||||
* \return \c true if recording to file starts without errors
|
||||
*/
|
||||
void setRecordDataFormat(RecordedDataMode dataMode);
|
||||
void setRecordDataFormat(SessionRecordingDataMode dataMode);
|
||||
|
||||
/**
|
||||
* Used to stop a recording in progress. If open, the recording file will be closed,
|
||||
@@ -246,11 +252,12 @@ public:
|
||||
*
|
||||
* \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 currentParsingLine string containing the most current line that was read
|
||||
* \param lineN line number in playback file where this keyframe resides
|
||||
*/
|
||||
static void readCameraKeyframeAscii(timestamps& times,
|
||||
datamessagestructures::CameraKeyframe& kf, std::string filenameRead, int lineN);
|
||||
datamessagestructures::CameraKeyframe& kf, std::string currentParsingLine,
|
||||
int lineN);
|
||||
|
||||
/**
|
||||
* Reads a time keyframe from a binary format playback file, and populates input
|
||||
@@ -270,11 +277,12 @@ public:
|
||||
*
|
||||
* \param times reference to a timestamps structure which contains recorded times
|
||||
* \param kf reference to a time keyframe which contains time details
|
||||
* \param filenameRead a string containing the playback filename
|
||||
* \param currentParsingLine string containing the most current line that was read
|
||||
* \param lineN line number in playback file where this keyframe resides
|
||||
*/
|
||||
static void readTimeKeyframeAscii(timestamps& times,
|
||||
datamessagestructures::TimeKeyframe& kf, std::string filenameRead, int lineN);
|
||||
datamessagestructures::TimeKeyframe& kf, std::string currentParsingLine,
|
||||
int lineN);
|
||||
|
||||
/**
|
||||
* Reads a script keyframe from a binary format playback file, and populates input
|
||||
@@ -296,11 +304,12 @@ public:
|
||||
* \param times reference to a timestamps structure which contains recorded times
|
||||
* \param kf reference to a script keyframe which contains the size of the script
|
||||
* (in chars) and the text itself
|
||||
* \param filenameRead a string containing the playback filename
|
||||
* \param currentParsingLine string containing the most current line that was read
|
||||
* \param lineN line number in playback file where this keyframe resides
|
||||
*/
|
||||
static void readScriptKeyframeAscii(timestamps& times,
|
||||
datamessagestructures::ScriptMessage& kf, std::string filenameRead, int lineN);
|
||||
datamessagestructures::ScriptMessage& kf, std::string currentParsingLine,
|
||||
int lineN);
|
||||
|
||||
/**
|
||||
* Writes a camera keyframe to a binary format recording file using a CameraKeyframe
|
||||
@@ -377,6 +386,35 @@ public:
|
||||
*/
|
||||
static std::string readHeaderElement(std::ifstream& stream, size_t readLen_chars);
|
||||
|
||||
/**
|
||||
* Writes a header to a binary recording file buffer
|
||||
*
|
||||
* \param times reference to a timestamps structure which contains recorded times
|
||||
* \param type single character signifying the keyframe type
|
||||
* \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,
|
||||
size_t& idx);
|
||||
|
||||
/**
|
||||
* Writes a header to an ascii recording file buffer
|
||||
*
|
||||
* \param times reference to a timestamps structure which contains recorded times
|
||||
* \param type string signifying the keyframe type
|
||||
* \param line the stringstream buffer being written to
|
||||
*/
|
||||
static void saveHeaderAscii(timestamps times, const std::string& type,
|
||||
std::stringstream& line);
|
||||
|
||||
/**
|
||||
* Saves a keyframe to an ascii recording file
|
||||
*
|
||||
* \param entry the ascii string version of the keyframe (any type)
|
||||
* \param file ofstream object to write to
|
||||
*/
|
||||
static void saveKeyframeToFile(std::string entry, std::ofstream& file);
|
||||
|
||||
private:
|
||||
enum class RecordedType {
|
||||
Camera = 0,
|
||||
@@ -409,7 +447,6 @@ private:
|
||||
std::ofstream& file);
|
||||
static void saveKeyframeToFileBinary(unsigned char* bufferSource, size_t size,
|
||||
std::ofstream& file);
|
||||
static void saveKeyframeToFile(std::string entry, std::ofstream& file);
|
||||
|
||||
void addKeyframe(double timestamp,
|
||||
interaction::KeyframeNavigator::CameraPose keyframe);
|
||||
@@ -439,12 +476,7 @@ private:
|
||||
static void writeToFileBuffer(unsigned char* buf, size_t& idx, unsigned char c);
|
||||
static void writeToFileBuffer(unsigned char* buf, size_t& idx, bool b);
|
||||
|
||||
static void saveHeaderBinary(timestamps times, char type,
|
||||
unsigned char* kfBuffer, size_t& idx);
|
||||
static void saveHeaderAscii(timestamps times, const std::string& type,
|
||||
std::stringstream& line);
|
||||
|
||||
RecordedDataMode _recordingDataMode = RecordedDataMode::Binary;
|
||||
SessionRecordingDataMode _recordingDataMode = SessionRecordingDataMode::Binary;
|
||||
SessionState _state = SessionState::Idle;
|
||||
SessionState _lastState = SessionState::Idle;
|
||||
std::string _playbackFilename;
|
||||
|
||||
@@ -53,20 +53,19 @@ public:
|
||||
void perform(const Task::ProgressCallback& progressCallback) override;
|
||||
static documentation::Documentation documentation();
|
||||
void convert();
|
||||
SessionRecording::RecordedDataMode ConvertRecFormatTask::formatType();
|
||||
|
||||
private:
|
||||
void convertToAscii();
|
||||
void convertToBinary();
|
||||
void determineFormatType();
|
||||
std::string addFileSuffix(const std::string& filePath, const std::string& suffix);
|
||||
std::string _inFilePath;
|
||||
std::string _outFilePath;
|
||||
std::ifstream _iFile;
|
||||
std::ofstream _oFile;
|
||||
SessionRecordingDataMode _fileFormatType;
|
||||
|
||||
std::string _valueFunctionLua;
|
||||
|
||||
SessionRecording sr;
|
||||
};
|
||||
|
||||
} // namespace openspace::interaction
|
||||
|
||||
@@ -429,6 +429,12 @@ struct ScriptMessage {
|
||||
double _timestamp;
|
||||
|
||||
void serialize(std::vector<char> &buffer) const {
|
||||
size_t strLen = _script.size();
|
||||
size_t writeSize_bytes = sizeof(size_t);
|
||||
|
||||
unsigned char const *p = reinterpret_cast<unsigned char const*>(&strLen);
|
||||
buffer.insert(buffer.end(), p, p + writeSize_bytes);
|
||||
|
||||
buffer.insert(buffer.end(), _script.begin(), _script.end());
|
||||
};
|
||||
|
||||
@@ -486,6 +492,8 @@ struct ScriptMessage {
|
||||
_script.erase();
|
||||
for (int i = 0; i < numScriptLines; ++i) {
|
||||
std::getline(iss, tmpReadbackScript);
|
||||
size_t start = tmpReadbackScript.find_first_not_of(" ");
|
||||
tmpReadbackScript = tmpReadbackScript.substr(start);
|
||||
_script.append(tmpReadbackScript);
|
||||
if (i < (numScriptLines - 1)) {
|
||||
_script.append("\n");
|
||||
|
||||
@@ -63,6 +63,7 @@ set(OPENSPACE_SOURCE
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/shortcutmanager_lua.inl
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/websocketinputstate.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/websocketcamerastates.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/interaction/tasks/convertrecformattask.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/mission/mission.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/mission/missionmanager.cpp
|
||||
${OPENSPACE_BASE_DIR}/src/mission/missionmanager_lua.inl
|
||||
@@ -245,6 +246,7 @@ set(OPENSPACE_HEADER
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/shortcutmanager.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/websocketinputstate.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/websocketcamerastates.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/interaction/tasks/convertrecformattask.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/mission/mission.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/mission/missionmanager.h
|
||||
${OPENSPACE_BASE_DIR}/include/openspace/network/parallelconnection.h
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <openspace/interaction/keyframenavigator.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/interaction/orbitalnavigator.h>
|
||||
#include <openspace/interaction/tasks/convertrecformattask.h>
|
||||
#include <openspace/rendering/luaconsole.h>
|
||||
#include <openspace/rendering/renderable.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
@@ -36,6 +37,8 @@
|
||||
#include <openspace/scripting/scriptengine.h>
|
||||
#include <openspace/scripting/scriptscheduler.h>
|
||||
#include <openspace/util/camera.h>
|
||||
#include <openspace/util/factorymanager.h>
|
||||
#include <openspace/util/task.h>
|
||||
#include <openspace/util/timemanager.h>
|
||||
#include <ghoul/filesystem/file.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
@@ -57,7 +60,11 @@ namespace openspace::interaction {
|
||||
|
||||
SessionRecording::SessionRecording()
|
||||
: properties::PropertyOwner({ "SessionRecording", "Session Recording" })
|
||||
{}
|
||||
{
|
||||
auto fTask = FactoryManager::ref().factory<Task>();
|
||||
ghoul_assert(fRenderable, "No task factory existed");
|
||||
fTask->registerClass<ConvertRecFormatTask>("ConvertRecFormatTask");
|
||||
}
|
||||
|
||||
SessionRecording::~SessionRecording() {} // NOLINT
|
||||
|
||||
@@ -66,7 +73,7 @@ void SessionRecording::deinitialize() {
|
||||
stopPlayback();
|
||||
}
|
||||
|
||||
void SessionRecording::setRecordDataFormat(RecordedDataMode dataMode) {
|
||||
void SessionRecording::setRecordDataFormat(SessionRecordingDataMode dataMode) {
|
||||
_recordingDataMode = dataMode;
|
||||
}
|
||||
|
||||
@@ -102,7 +109,7 @@ bool SessionRecording::startRecording(const std::string& filename) {
|
||||
_playbackActive_camera = false;
|
||||
_playbackActive_time = false;
|
||||
_playbackActive_script = false;
|
||||
if (_recordingDataMode == RecordedDataMode::Binary) {
|
||||
if (_recordingDataMode == SessionRecordingDataMode::Binary) {
|
||||
_recordFile.open(absFilename, std::ios::binary);
|
||||
}
|
||||
else {
|
||||
@@ -115,9 +122,9 @@ bool SessionRecording::startRecording(const std::string& filename) {
|
||||
));
|
||||
return false;
|
||||
}
|
||||
_recordFile << FileHeaderTitle;
|
||||
_recordFile << SessionRecordingFileHeaderTitle;
|
||||
_recordFile.write(FileHeaderVersion, FileHeaderVersionLength);
|
||||
if (_recordingDataMode == RecordedDataMode::Binary) {
|
||||
if (_recordingDataMode == SessionRecordingDataMode::Binary) {
|
||||
_recordFile << DataFormatBinaryTag;
|
||||
}
|
||||
else {
|
||||
@@ -180,9 +187,9 @@ bool SessionRecording::startPlayback(const std::string& filename,
|
||||
// Read header
|
||||
std::string readBackHeaderString = readHeaderElement(
|
||||
_playbackFile,
|
||||
FileHeaderTitle.length()
|
||||
SessionRecordingFileHeaderTitle.length()
|
||||
);
|
||||
if (readBackHeaderString != FileHeaderTitle) {
|
||||
if (readBackHeaderString != SessionRecordingFileHeaderTitle) {
|
||||
LERROR("Specified playback file does not contain expected header.");
|
||||
cleanUpPlayback();
|
||||
return false;
|
||||
@@ -190,10 +197,10 @@ bool SessionRecording::startPlayback(const std::string& filename,
|
||||
readHeaderElement(_playbackFile, FileHeaderVersionLength);
|
||||
std::string readDataMode = readHeaderElement(_playbackFile, 1);
|
||||
if (readDataMode[0] == DataFormatAsciiTag) {
|
||||
_recordingDataMode = RecordedDataMode::Ascii;
|
||||
_recordingDataMode = SessionRecordingDataMode::Ascii;
|
||||
}
|
||||
else if (readDataMode[0] == DataFormatBinaryTag) {
|
||||
_recordingDataMode = RecordedDataMode::Binary;
|
||||
_recordingDataMode = SessionRecordingDataMode::Binary;
|
||||
}
|
||||
else {
|
||||
LERROR("Unknown data type in header (should be Ascii or Binary)");
|
||||
@@ -201,13 +208,14 @@ bool SessionRecording::startPlayback(const std::string& filename,
|
||||
}
|
||||
std::string throwawayNewlineChar = readHeaderElement(_playbackFile, 1);
|
||||
|
||||
if (_recordingDataMode == RecordedDataMode::Binary) {
|
||||
if (_recordingDataMode == SessionRecordingDataMode::Binary) {
|
||||
//Close & re-open the file, starting from the beginning, and do dummy read
|
||||
// past the header, version, and data type
|
||||
_playbackFile.close();
|
||||
_playbackFile.open(_playbackFilename, std::ifstream::in | std::ios::binary);
|
||||
size_t headerSize = FileHeaderTitle.length() + FileHeaderVersionLength +
|
||||
sizeof(DataFormatBinaryTag) + sizeof('\n');
|
||||
size_t headerSize = SessionRecordingFileHeaderTitle.length() +
|
||||
FileHeaderVersionLength +
|
||||
sizeof(DataFormatBinaryTag) + sizeof('\n');
|
||||
_playbackFile.read(reinterpret_cast<char*>(&_keyframeBuffer), headerSize);
|
||||
}
|
||||
|
||||
@@ -443,7 +451,7 @@ void SessionRecording::saveCameraKeyframe() {
|
||||
kf._timestamp - _timestampRecordStarted,
|
||||
global::timeManager.time().j2000Seconds()
|
||||
};
|
||||
if (_recordingDataMode == RecordedDataMode::Binary) {
|
||||
if (_recordingDataMode == SessionRecordingDataMode::Binary) {
|
||||
saveCameraKeyframeBinary(times, kf, _keyframeBuffer, _recordFile);
|
||||
}
|
||||
else {
|
||||
@@ -479,7 +487,7 @@ void SessionRecording::saveCameraKeyframeBinary(timestamps times,
|
||||
{
|
||||
// Writing to a binary session recording file
|
||||
size_t idx = 0;
|
||||
saveHeaderBinary(times, 'c', kfBuffer, idx);
|
||||
saveHeaderBinary(times, SessionRecordingHeaderCameraBinary, kfBuffer, idx);
|
||||
// Writing to internal buffer, and then to file, for performance reasons
|
||||
std::vector<char> writeBuffer;
|
||||
kf.serialize(writeBuffer);
|
||||
@@ -492,7 +500,7 @@ void SessionRecording::saveCameraKeyframeAscii(timestamps times,
|
||||
std::ofstream& file)
|
||||
{
|
||||
std::stringstream keyframeLine = std::stringstream();
|
||||
saveHeaderAscii(times, "camera", keyframeLine);
|
||||
saveHeaderAscii(times, SessionRecordingHeaderCameraAscii, keyframeLine);
|
||||
kf.write(keyframeLine);
|
||||
saveKeyframeToFile(keyframeLine.str(), file);
|
||||
}
|
||||
@@ -510,7 +518,7 @@ void SessionRecording::saveTimeKeyframe() {
|
||||
kf._timestamp - _timestampRecordStarted,
|
||||
global::timeManager.time().j2000Seconds()
|
||||
};
|
||||
if (_recordingDataMode == RecordedDataMode::Binary) {
|
||||
if (_recordingDataMode == SessionRecordingDataMode::Binary) {
|
||||
saveTimeKeyframeBinary(times, kf, _keyframeBuffer, _recordFile);
|
||||
} else {
|
||||
saveTimeKeyframeAscii(times, kf, _recordFile);
|
||||
@@ -523,7 +531,7 @@ void SessionRecording::saveTimeKeyframeBinary(timestamps times,
|
||||
std::ofstream& file)
|
||||
{
|
||||
size_t idx = 0;
|
||||
saveHeaderBinary(times, 't', kfBuffer, idx);
|
||||
saveHeaderBinary(times, SessionRecordingHeaderTimeBinary, kfBuffer, idx);
|
||||
std::vector<char> writeBuffer;
|
||||
kf.serialize(writeBuffer);
|
||||
writeToFileBuffer(kfBuffer, idx, writeBuffer);
|
||||
@@ -535,7 +543,7 @@ void SessionRecording::saveTimeKeyframeAscii(timestamps times,
|
||||
std::ofstream& file)
|
||||
{
|
||||
std::stringstream keyframeLine = std::stringstream();
|
||||
saveHeaderAscii(times, "time", keyframeLine);
|
||||
saveHeaderAscii(times, SessionRecordingHeaderTimeAscii, keyframeLine);
|
||||
kf.write(keyframeLine);
|
||||
saveKeyframeToFile(keyframeLine.str(), file);
|
||||
}
|
||||
@@ -554,7 +562,7 @@ void SessionRecording::saveScriptKeyframe(std::string scriptToSave) {
|
||||
global::timeManager.time().j2000Seconds()
|
||||
};
|
||||
|
||||
if (_recordingDataMode == RecordedDataMode::Binary) {
|
||||
if (_recordingDataMode == SessionRecordingDataMode::Binary) {
|
||||
saveScriptKeyframeBinary(times, sm, _keyframeBuffer, _recordFile);
|
||||
}
|
||||
else {
|
||||
@@ -568,11 +576,12 @@ void SessionRecording::saveScriptKeyframeBinary(timestamps times,
|
||||
std::ofstream& file)
|
||||
{
|
||||
size_t idx = 0;
|
||||
saveHeaderBinary(times, 's', smBuffer, idx);
|
||||
//Write script header to file
|
||||
saveHeaderBinary(times, SessionRecordingHeaderScriptBinary, smBuffer, idx);
|
||||
// Writing to internal buffer, and then to file, for performance reasons
|
||||
std::vector<char> writeBuffer;
|
||||
sm.serialize(writeBuffer);
|
||||
writeToFileBuffer(smBuffer, idx, writeBuffer);
|
||||
saveKeyframeToFileBinary(smBuffer, idx, file);
|
||||
//Write script data to file
|
||||
sm.write(smBuffer, idx, file);
|
||||
}
|
||||
|
||||
void SessionRecording::saveScriptKeyframeAscii(timestamps times,
|
||||
@@ -581,7 +590,7 @@ void SessionRecording::saveScriptKeyframeAscii(timestamps times,
|
||||
{
|
||||
|
||||
std::stringstream keyframeLine = std::stringstream();
|
||||
saveHeaderAscii(times, "script", keyframeLine);
|
||||
saveHeaderAscii(times, SessionRecordingHeaderScriptAscii, keyframeLine);
|
||||
sm.write(keyframeLine);
|
||||
saveKeyframeToFile(keyframeLine.str(), file);
|
||||
}
|
||||
@@ -632,7 +641,7 @@ SessionRecording::SessionState SessionRecording::state() const {
|
||||
bool SessionRecording::playbackAddEntriesToTimeline() {
|
||||
bool parsingErrorsFound = false;
|
||||
|
||||
if (_recordingDataMode == RecordedDataMode::Binary) {
|
||||
if (_recordingDataMode == SessionRecordingDataMode::Binary) {
|
||||
unsigned char frameType;
|
||||
bool fileReadOk = true;
|
||||
|
||||
@@ -647,13 +656,13 @@ bool SessionRecording::playbackAddEntriesToTimeline() {
|
||||
fileReadOk = false;
|
||||
break;
|
||||
}
|
||||
if (frameType == 'c') {
|
||||
if (frameType == SessionRecordingHeaderCameraBinary) {
|
||||
playbackCamera();
|
||||
}
|
||||
else if (frameType == 't') {
|
||||
else if (frameType == SessionRecordingHeaderTimeBinary) {
|
||||
playbackTimeChange();
|
||||
}
|
||||
else if (frameType == 's') {
|
||||
else if (frameType == SessionRecordingHeaderScriptBinary) {
|
||||
playbackScript();
|
||||
}
|
||||
else {
|
||||
@@ -682,13 +691,13 @@ bool SessionRecording::playbackAddEntriesToTimeline() {
|
||||
break;
|
||||
}
|
||||
|
||||
if (entryType == "camera") {
|
||||
if (entryType == SessionRecordingHeaderCameraAscii) {
|
||||
playbackCamera();
|
||||
}
|
||||
else if (entryType == "time") {
|
||||
else if (entryType == SessionRecordingHeaderTimeAscii) {
|
||||
playbackTimeChange();
|
||||
}
|
||||
else if (entryType == "script") {
|
||||
else if (entryType == SessionRecordingHeaderScriptAscii) {
|
||||
playbackScript();
|
||||
}
|
||||
else {
|
||||
@@ -788,7 +797,7 @@ void SessionRecording::playbackCamera() {
|
||||
timestamps times;
|
||||
datamessagestructures::CameraKeyframe kf;
|
||||
|
||||
if (_recordingDataMode == RecordedDataMode::Binary) {
|
||||
if (_recordingDataMode == SessionRecordingDataMode::Binary) {
|
||||
readCameraKeyframeBinary(times, kf, _playbackFile, _playbackLineNum);
|
||||
}
|
||||
else {
|
||||
@@ -843,16 +852,18 @@ void SessionRecording::readCameraKeyframeBinary(timestamps& times,
|
||||
|
||||
void SessionRecording::readCameraKeyframeAscii(timestamps& times,
|
||||
datamessagestructures::CameraKeyframe& kf,
|
||||
std::string filenameRead,
|
||||
std::string currentParsingLine,
|
||||
int lineN)
|
||||
{
|
||||
std::string rotationFollowing;
|
||||
std::string entryType;
|
||||
|
||||
std::istringstream iss(filenameRead);
|
||||
std::istringstream iss(currentParsingLine);
|
||||
iss >> entryType;
|
||||
iss >> times.timeOs >> times.timeRec >> times.timeSim;
|
||||
kf.read(iss);
|
||||
//ASCII format does not contain trailing timestamp so add it here
|
||||
kf._timestamp = times.timeOs;
|
||||
|
||||
if (iss.fail() || !iss.eof()) {
|
||||
LERROR(fmt::format("Error parsing camera line {} of playback file", lineN));
|
||||
@@ -864,7 +875,7 @@ void SessionRecording::playbackTimeChange() {
|
||||
timestamps times;
|
||||
datamessagestructures::TimeKeyframe kf;
|
||||
|
||||
if (_recordingDataMode == RecordedDataMode::Binary) {
|
||||
if (_recordingDataMode == SessionRecordingDataMode::Binary) {
|
||||
readTimeKeyframeBinary(times, kf, _playbackFile, _playbackLineNum);
|
||||
} else {
|
||||
readTimeKeyframeAscii(times, kf, _playbackLineParsing, _playbackLineNum);
|
||||
@@ -913,12 +924,12 @@ void SessionRecording::readTimeKeyframeBinary(timestamps& times,
|
||||
|
||||
void SessionRecording::readTimeKeyframeAscii(timestamps& times,
|
||||
datamessagestructures::TimeKeyframe& kf,
|
||||
std::string filenameRead,
|
||||
std::string currentParsingLine,
|
||||
int lineN)
|
||||
{
|
||||
std::string entryType;
|
||||
|
||||
std::istringstream iss(filenameRead);
|
||||
std::istringstream iss(currentParsingLine);
|
||||
iss >> entryType;
|
||||
iss >> times.timeOs >> times.timeRec >> times.timeSim;
|
||||
kf.read(iss);
|
||||
@@ -931,8 +942,8 @@ void SessionRecording::readTimeKeyframeAscii(timestamps& times,
|
||||
}
|
||||
}
|
||||
|
||||
static std::string SessionRecording::readHeaderElement(std::ifstream& stream,
|
||||
size_t readLen_chars)
|
||||
std::string SessionRecording::readHeaderElement(std::ifstream& stream,
|
||||
size_t readLen_chars)
|
||||
{
|
||||
std::vector<char> readTemp(readLen_chars);
|
||||
stream.read(&readTemp[0], readLen_chars);
|
||||
@@ -943,7 +954,7 @@ void SessionRecording::playbackScript() {
|
||||
timestamps times;
|
||||
datamessagestructures::ScriptMessage kf;
|
||||
|
||||
if (_recordingDataMode == RecordedDataMode::Binary) {
|
||||
if (_recordingDataMode == SessionRecordingDataMode::Binary) {
|
||||
readScriptKeyframeBinary(times, kf, _playbackFile, _playbackLineNum);
|
||||
} else {
|
||||
readScriptKeyframeAscii(times, kf, _playbackLineParsing, _playbackLineNum);
|
||||
@@ -990,11 +1001,11 @@ void SessionRecording::readScriptKeyframeBinary(timestamps& times,
|
||||
|
||||
void SessionRecording::readScriptKeyframeAscii(timestamps& times,
|
||||
datamessagestructures::ScriptMessage& kf,
|
||||
std::string filenameRead,
|
||||
std::string currentParsingLine,
|
||||
int lineN)
|
||||
{
|
||||
std::string entryType;
|
||||
std::istringstream iss(filenameRead);
|
||||
std::istringstream iss(currentParsingLine);
|
||||
iss >> entryType;
|
||||
iss >> times.timeOs >> times.timeRec >> times.timeSim;
|
||||
kf.read(iss);
|
||||
@@ -1156,11 +1167,6 @@ bool SessionRecording::doesTimelineEntryContainCamera(unsigned int index) const
|
||||
}
|
||||
|
||||
bool SessionRecording::processNextNonCameraKeyframeAheadInTime() {
|
||||
//LINFO(fmt::format(
|
||||
// "Keyframe at {} frame={} timelineIndex={}",
|
||||
// now, global::renderEngine._frameNumber, _idxTimeline
|
||||
//));
|
||||
|
||||
switch (getNextKeyframeType()) {
|
||||
case RecordedType::Camera:
|
||||
// Just return true since this function no longer handles camera keyframes
|
||||
|
||||
@@ -40,7 +40,7 @@ int startRecording(lua_State* L) {
|
||||
return luaL_error(L, "filepath string is empty");
|
||||
}
|
||||
global::sessionRecording.setRecordDataFormat(
|
||||
openspace::interaction::SessionRecording::RecordedDataMode::Binary
|
||||
openspace::interaction::SessionRecordingDataMode::Binary
|
||||
);
|
||||
global::sessionRecording.startRecording(recordFilePath);
|
||||
|
||||
@@ -63,7 +63,7 @@ int startRecordingAscii(lua_State* L) {
|
||||
return luaL_error(L, "filepath string is empty");
|
||||
}
|
||||
global::sessionRecording.setRecordDataFormat(
|
||||
openspace::interaction::SessionRecording::RecordedDataMode::Ascii
|
||||
openspace::interaction::SessionRecordingDataMode::Ascii
|
||||
);
|
||||
global::sessionRecording.startRecording(recordFilePath);
|
||||
|
||||
|
||||
@@ -51,11 +51,11 @@ ConvertRecFormatTask::ConvertRecFormatTask(const ghoul::Dictionary& dictionary)
|
||||
ghoul_assert(FileSys.fileExists(_inFilePath), "The filename must exist");
|
||||
if (!FileSys.fileExists(_inFilePath)) {
|
||||
LERROR(fmt::format("Failed to load session recording file: {}", _inFilePath));
|
||||
//throw ghoul::FileNotFoundError(_inFilePath);
|
||||
}
|
||||
|
||||
_iFile.exceptions(std::ofstream::failbit | std::ofstream::badbit);
|
||||
_iFile.open(_inFilePath);
|
||||
else {
|
||||
_iFile.open(_inFilePath, std::ifstream::in);
|
||||
determineFormatType();
|
||||
}
|
||||
}
|
||||
|
||||
ConvertRecFormatTask::~ConvertRecFormatTask() {
|
||||
@@ -63,17 +63,42 @@ ConvertRecFormatTask::~ConvertRecFormatTask() {
|
||||
_oFile.close();
|
||||
}
|
||||
|
||||
void ConvertRecFormatTask::perform(const Task::ProgressCallback& progressCallback) {
|
||||
std::string ConvertRecFormatTask::description() {
|
||||
std::string description = "Convert session recording file '" + _inFilePath + "' ";
|
||||
if (_fileFormatType == SessionRecordingDataMode::Ascii) {
|
||||
description += "(ascii format) ";
|
||||
}
|
||||
else if (_fileFormatType == SessionRecordingDataMode::Binary) {
|
||||
description += "(binary format) ";
|
||||
}
|
||||
else {
|
||||
description += "(UNKNOWN format) ";
|
||||
}
|
||||
description += "conversion to file '" + _outFilePath + "'.";
|
||||
return description;
|
||||
}
|
||||
|
||||
void ConvertRecFormatTask::perform(const Task::ProgressCallback& progressCallback) {
|
||||
convert();
|
||||
}
|
||||
|
||||
void ConvertRecFormatTask::convert() {
|
||||
SessionRecording::RecordedDataMode type = formatType();
|
||||
if (_fileFormatType == SessionRecordingDataMode::Ascii) {
|
||||
_oFile.open(_outFilePath);
|
||||
}
|
||||
else if (_fileFormatType == SessionRecordingDataMode::Binary) {
|
||||
_oFile.open(_outFilePath, std::ios::binary);
|
||||
}
|
||||
_oFile.write(SessionRecordingFileHeaderTitle.c_str(),
|
||||
SessionRecordingFileHeaderTitle.length());
|
||||
_oFile.write(SessionRecording::FileHeaderVersion,
|
||||
SessionRecording::FileHeaderVersionLength);
|
||||
_oFile.close();
|
||||
|
||||
if (type == SessionRecording::RecordedDataMode::Ascii) {
|
||||
if (_fileFormatType == SessionRecordingDataMode::Ascii) {
|
||||
convertToBinary();
|
||||
}
|
||||
else if (type == SessionRecording::RecordedDataMode::Binary) {
|
||||
else if (_fileFormatType == SessionRecordingDataMode::Binary) {
|
||||
convertToAscii();
|
||||
}
|
||||
else {
|
||||
@@ -82,27 +107,31 @@ void ConvertRecFormatTask::convert() {
|
||||
}
|
||||
}
|
||||
|
||||
SessionRecording::RecordedDataMode ConvertRecFormatTask::formatType() {
|
||||
const std::string expectedHeader = "OpenSpace_record/playback";
|
||||
void ConvertRecFormatTask::determineFormatType() {
|
||||
_fileFormatType = SessionRecordingDataMode::Unknown;
|
||||
std::string line;
|
||||
//Get first line, which is ASCII regardless of format
|
||||
std::getline(_iFile, line);
|
||||
|
||||
if (line.substr(0, SessionRecording::FileHeaderTitle.length())
|
||||
!= SessionRecording::FileHeaderTitle)
|
||||
line = SessionRecording::readHeaderElement(_iFile,
|
||||
SessionRecordingFileHeaderTitle.length());
|
||||
|
||||
if (line.substr(0, SessionRecordingFileHeaderTitle.length())
|
||||
!= SessionRecordingFileHeaderTitle)
|
||||
{
|
||||
LERROR(fmt::format("Session recording file {} does not have expected header.", _inFilePath));
|
||||
return SessionRecording::RecordedDataMode::Binary + 1;
|
||||
LERROR(fmt::format("Session recording file {} does not have expected header.",
|
||||
_inFilePath));
|
||||
}
|
||||
else {
|
||||
if (line.back() == SessionRecording::DataFormatAsciiTag) {
|
||||
return SessionRecording::RecordedDataMode::Ascii;
|
||||
//Read version string and throw it away (and also line feed character at end)
|
||||
SessionRecording::readHeaderElement(_iFile,
|
||||
SessionRecording::FileHeaderVersionLength);
|
||||
line = SessionRecording::readHeaderElement(_iFile, 1);
|
||||
SessionRecording::readHeaderElement(_iFile, 1);
|
||||
|
||||
if (line.at(0) == SessionRecording::DataFormatAsciiTag) {
|
||||
_fileFormatType = SessionRecordingDataMode::Ascii;
|
||||
}
|
||||
else if (line.back() == SessionRecording::DataFormatBinaryTag) {
|
||||
return SessionRecording::RecordedDataMode::Binary;
|
||||
}
|
||||
else {
|
||||
return SessionRecording::RecordedDataMode::Binary + 1;
|
||||
else if (line.at(0) == SessionRecording::DataFormatBinaryTag) {
|
||||
_fileFormatType = SessionRecordingDataMode::Binary;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -114,8 +143,10 @@ void ConvertRecFormatTask::convertToAscii() {
|
||||
datamessagestructures::ScriptMessage skf;
|
||||
int lineNum = 1;
|
||||
unsigned char frameType;
|
||||
_outFilePath = addFileSuffix(_inFilePath, "_ascii");
|
||||
std::stringstream keyframeLine = std::stringstream();
|
||||
_oFile.open(_outFilePath, std::ifstream::app);
|
||||
char tmpType = SessionRecording::DataFormatAsciiTag;
|
||||
_oFile.write(&tmpType, 1);
|
||||
_oFile.write("\n", 1);
|
||||
|
||||
bool fileReadOk = true;
|
||||
while (fileReadOk) {
|
||||
@@ -130,20 +161,24 @@ void ConvertRecFormatTask::convertToAscii() {
|
||||
break;
|
||||
}
|
||||
|
||||
std::stringstream keyframeLine = std::stringstream();
|
||||
keyframeLine.str(std::string());
|
||||
if (frameType == 'c') {
|
||||
if (frameType == SessionRecordingHeaderCameraBinary) {
|
||||
SessionRecording::readCameraKeyframeBinary(times, ckf, _iFile, lineNum);
|
||||
SessionRecording::saveHeaderAscii(times, "camera", keyframeLine);
|
||||
SessionRecording::saveHeaderAscii(times, SessionRecordingHeaderCameraAscii,
|
||||
keyframeLine);
|
||||
ckf.write(keyframeLine);
|
||||
}
|
||||
else if (frameType == 't') {
|
||||
else if (frameType == SessionRecordingHeaderTimeBinary) {
|
||||
SessionRecording::readTimeKeyframeBinary(times, tkf, _iFile, lineNum);
|
||||
SessionRecording::saveHeaderAscii(times, "time", keyframeLine);
|
||||
SessionRecording::saveHeaderAscii(times, SessionRecordingHeaderTimeAscii,
|
||||
keyframeLine);
|
||||
tkf.write(keyframeLine);
|
||||
}
|
||||
else if (frameType == 's') {
|
||||
else if (frameType == SessionRecordingHeaderScriptBinary) {
|
||||
SessionRecording::readScriptKeyframeBinary(times, skf, _iFile, lineNum);
|
||||
SessionRecording::saveHeaderAscii(times, "script", keyframeLine);
|
||||
SessionRecording::saveHeaderAscii(times, SessionRecordingHeaderScriptAscii,
|
||||
keyframeLine);
|
||||
skf.write(keyframeLine);
|
||||
}
|
||||
else {
|
||||
@@ -156,6 +191,7 @@ void ConvertRecFormatTask::convertToAscii() {
|
||||
SessionRecording::saveKeyframeToFile(keyframeLine.str(), _oFile);
|
||||
lineNum++;
|
||||
}
|
||||
_oFile.close();
|
||||
}
|
||||
|
||||
void ConvertRecFormatTask::convertToBinary() {
|
||||
@@ -166,8 +202,10 @@ void ConvertRecFormatTask::convertToBinary() {
|
||||
int lineNum = 1;
|
||||
std::string lineContents;
|
||||
unsigned char keyframeBuffer[SessionRecording::_saveBufferMaxSize_bytes];
|
||||
std::ofstream saveFile;
|
||||
saveFile.open(_outFilePath, std::ios::binary);
|
||||
_oFile.open(_outFilePath, std::ifstream::app | std::ios::binary);
|
||||
char tmpType = SessionRecording::DataFormatBinaryTag;
|
||||
_oFile.write(&tmpType, 1);
|
||||
_oFile.write("\n", 1);
|
||||
size_t idx = 0;
|
||||
|
||||
while (std::getline(_iFile, lineContents)) {
|
||||
@@ -183,20 +221,20 @@ void ConvertRecFormatTask::convertToBinary() {
|
||||
break;
|
||||
}
|
||||
|
||||
if (entryType == "camera") {
|
||||
SessionRecording::readCameraKeyframeAscii(times, ckf, _inFilePath, lineNum);
|
||||
if (entryType == SessionRecordingHeaderCameraAscii) {
|
||||
SessionRecording::readCameraKeyframeAscii(times, ckf, lineContents, lineNum);
|
||||
SessionRecording::saveCameraKeyframeBinary(times, ckf, keyframeBuffer,
|
||||
saveFile);
|
||||
_oFile);
|
||||
}
|
||||
else if (entryType == "time") {
|
||||
SessionRecording::readTimeKeyframeAscii(times, tkf, _inFilePath, lineNum);
|
||||
else if (entryType == SessionRecordingHeaderTimeAscii) {
|
||||
SessionRecording::readTimeKeyframeAscii(times, tkf, lineContents, lineNum);
|
||||
SessionRecording::saveTimeKeyframeBinary(times, tkf, keyframeBuffer,
|
||||
saveFile);
|
||||
_oFile);
|
||||
}
|
||||
else if (entryType == "script") {
|
||||
SessionRecording::readScriptKeyframeAscii(times, skf, _inFilePath, lineNum);
|
||||
else if (entryType == SessionRecordingHeaderScriptAscii) {
|
||||
SessionRecording::readScriptKeyframeAscii(times, skf, lineContents, lineNum);
|
||||
SessionRecording::saveScriptKeyframeBinary(times, skf, keyframeBuffer,
|
||||
saveFile);
|
||||
_oFile);
|
||||
}
|
||||
else {
|
||||
LERROR(fmt::format(
|
||||
@@ -206,7 +244,7 @@ void ConvertRecFormatTask::convertToBinary() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
saveFile.close();
|
||||
_oFile.close();
|
||||
LINFO(fmt::format(
|
||||
"Finished converting {} entries from file {}",
|
||||
lineNum, _inFilePath
|
||||
|
||||
Reference in New Issue
Block a user