mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-04 04:24:47 +02:00
Merge pull request #10597 from druiz17/record-standard
Saved recording are officially g zipped and pose are played back to the standard endpoint
This commit is contained in:
commit
f47a49e631
5 changed files with 53 additions and 44 deletions
|
@ -19,6 +19,7 @@
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
#include <PathUtils.h>
|
#include <PathUtils.h>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
#include <Gzip.h>
|
||||||
|
|
||||||
#include <BuildInfo.h>
|
#include <BuildInfo.h>
|
||||||
#include <GLMHelpers.h>
|
#include <GLMHelpers.h>
|
||||||
|
@ -27,7 +28,7 @@
|
||||||
|
|
||||||
QString SAVE_DIRECTORY = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + "/" + BuildInfo::MODIFIED_ORGANIZATION + "/" + BuildInfo::INTERFACE_NAME + "/hifi-input-recordings/";
|
QString SAVE_DIRECTORY = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + "/" + BuildInfo::MODIFIED_ORGANIZATION + "/" + BuildInfo::INTERFACE_NAME + "/hifi-input-recordings/";
|
||||||
QString FILE_PREFIX_NAME = "input-recording-";
|
QString FILE_PREFIX_NAME = "input-recording-";
|
||||||
QString COMPRESS_EXTENSION = "json.gz";
|
QString COMPRESS_EXTENSION = ".json.gz";
|
||||||
namespace controller {
|
namespace controller {
|
||||||
|
|
||||||
QJsonObject poseToJsonObject(const Pose pose) {
|
QJsonObject poseToJsonObject(const Pose pose) {
|
||||||
|
@ -93,23 +94,26 @@ namespace controller {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void exportToFile(const QJsonObject& object) {
|
void exportToFile(const QJsonObject& object, const QString& fileName) {
|
||||||
if (!QDir(SAVE_DIRECTORY).exists()) {
|
if (!QDir(SAVE_DIRECTORY).exists()) {
|
||||||
QDir().mkdir(SAVE_DIRECTORY);
|
QDir().mkdir(SAVE_DIRECTORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString timeStamp = QDateTime::currentDateTime().toString(Qt::ISODate);
|
|
||||||
timeStamp.replace(":", "-");
|
|
||||||
QString fileName = SAVE_DIRECTORY + FILE_PREFIX_NAME + timeStamp + COMPRESS_EXTENSION;
|
|
||||||
qDebug() << fileName;
|
|
||||||
QFile saveFile (fileName);
|
QFile saveFile (fileName);
|
||||||
if (!saveFile.open(QIODevice::WriteOnly)) {
|
if (!saveFile.open(QIODevice::WriteOnly)) {
|
||||||
qWarning() << "could not open file: " << fileName;
|
qWarning() << "could not open file: " << fileName;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QJsonDocument saveData(object);
|
QJsonDocument saveData(object);
|
||||||
QByteArray compressedData = qCompress(saveData.toJson(QJsonDocument::Compact));
|
QByteArray jsonData = saveData.toJson(QJsonDocument::Indented);
|
||||||
saveFile.write(compressedData);
|
QByteArray jsonDataForFile;
|
||||||
|
|
||||||
|
if (!gzip(jsonData, jsonDataForFile, -1)) {
|
||||||
|
qCritical("unable to gzip while saving to json.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
saveFile.write(jsonDataForFile);
|
||||||
saveFile.close();
|
saveFile.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,8 +125,16 @@ namespace controller {
|
||||||
status = false;
|
status = false;
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
QByteArray compressedData = qUncompress(openFile.readAll());
|
QByteArray compressedData = openFile.readAll();
|
||||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(compressedData);
|
QByteArray jsonData;
|
||||||
|
|
||||||
|
if (!gunzip(compressedData, jsonData)) {
|
||||||
|
qCritical() << "json file not in gzip format: " << file;
|
||||||
|
status = false;
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData);
|
||||||
object = jsonDoc.object();
|
object = jsonDoc.object();
|
||||||
status = true;
|
status = true;
|
||||||
openFile.close();
|
openFile.close();
|
||||||
|
@ -153,7 +165,7 @@ namespace controller {
|
||||||
QJsonObject InputRecorder::recordDataToJson() {
|
QJsonObject InputRecorder::recordDataToJson() {
|
||||||
QJsonObject data;
|
QJsonObject data;
|
||||||
data["frameCount"] = _framesRecorded;
|
data["frameCount"] = _framesRecorded;
|
||||||
data["version"] = "1.0";
|
data["version"] = "0.0";
|
||||||
|
|
||||||
QJsonArray actionArrayList;
|
QJsonArray actionArrayList;
|
||||||
QJsonArray poseArrayList;
|
QJsonArray poseArrayList;
|
||||||
|
@ -187,7 +199,10 @@ namespace controller {
|
||||||
|
|
||||||
void InputRecorder::saveRecording() {
|
void InputRecorder::saveRecording() {
|
||||||
QJsonObject jsonData = recordDataToJson();
|
QJsonObject jsonData = recordDataToJson();
|
||||||
exportToFile(jsonData);
|
QString timeStamp = QDateTime::currentDateTime().toString(Qt::ISODate);
|
||||||
|
timeStamp.replace(":", "-");
|
||||||
|
QString fileName = SAVE_DIRECTORY + FILE_PREFIX_NAME + timeStamp + COMPRESS_EXTENSION;
|
||||||
|
exportToFile(jsonData, fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputRecorder::loadRecording(const QString& path) {
|
void InputRecorder::loadRecording(const QString& path) {
|
||||||
|
@ -202,10 +217,12 @@ namespace controller {
|
||||||
QString filePath = urlPath.toLocalFile();
|
QString filePath = urlPath.toLocalFile();
|
||||||
QFileInfo info(filePath);
|
QFileInfo info(filePath);
|
||||||
QString extension = info.suffix();
|
QString extension = info.suffix();
|
||||||
|
|
||||||
if (extension != "gz") {
|
if (extension != "gz") {
|
||||||
qWarning() << "can not load file with exentsion of " << extension;
|
qWarning() << "can not load file with exentsion of " << extension;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool success = false;
|
bool success = false;
|
||||||
QJsonObject data = openFile(filePath, success);
|
QJsonObject data = openFile(filePath, success);
|
||||||
auto keyValue = data.find("version");
|
auto keyValue = data.find("version");
|
||||||
|
@ -233,34 +250,7 @@ namespace controller {
|
||||||
_poseStateList.push_back(_currentFramePoses);
|
_poseStateList.push_back(_currentFramePoses);
|
||||||
_currentFramePoses.clear();
|
_currentFramePoses.clear();
|
||||||
}
|
}
|
||||||
} else if (success) {
|
}
|
||||||
//convert recording to new reacording standard and rewrite file
|
|
||||||
auto userInputMapper = DependencyManager::get<UserInputMapper>();
|
|
||||||
_framesRecorded = data["frameCount"].toInt();
|
|
||||||
QJsonArray actionArrayList = data["actionList"].toArray();
|
|
||||||
QJsonArray poseArrayList = data["poseList"].toArray();
|
|
||||||
|
|
||||||
for (int actionIndex = 0; actionIndex < actionArrayList.size(); actionIndex++) {
|
|
||||||
QJsonArray actionState = actionArrayList[actionIndex].toArray();
|
|
||||||
for (int index = 0; index < actionState.size(); index++) {
|
|
||||||
QString actionName = userInputMapper->getActionName(Action(index));
|
|
||||||
_currentFrameActions[actionName] = actionState[index].toDouble();
|
|
||||||
}
|
|
||||||
_actionStateList.push_back(_currentFrameActions);
|
|
||||||
_currentFrameActions.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int poseIndex = 0; poseIndex < poseArrayList.size(); poseIndex++) {
|
|
||||||
QJsonArray poseState = poseArrayList[poseIndex].toArray();
|
|
||||||
for (int index = 0; index < poseState.size(); index++) {
|
|
||||||
QString actionName = userInputMapper->getActionName(Action(index));
|
|
||||||
_currentFramePoses[actionName] = jsonObjectToPose(poseState[index].toObject());
|
|
||||||
}
|
|
||||||
_poseStateList.push_back(_currentFramePoses);
|
|
||||||
_currentFramePoses.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_loading = false;
|
_loading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -329,6 +329,16 @@ QString UserInputMapper::getActionName(Action action) const {
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString UserInputMapper::getStandardPoseName(uint16_t pose) {
|
||||||
|
Locker locker(_lock);
|
||||||
|
for (auto posePair : getStandardInputs()) {
|
||||||
|
if (posePair.first.channel == pose && posePair.first.getType() == ChannelType::POSE) {
|
||||||
|
return posePair.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
QVector<QString> UserInputMapper::getActionNames() const {
|
QVector<QString> UserInputMapper::getActionNames() const {
|
||||||
Locker locker(_lock);
|
Locker locker(_lock);
|
||||||
QVector<QString> result;
|
QVector<QString> result;
|
||||||
|
|
|
@ -80,6 +80,7 @@ namespace controller {
|
||||||
|
|
||||||
QVector<Action> getAllActions() const;
|
QVector<Action> getAllActions() const;
|
||||||
QString getActionName(Action action) const;
|
QString getActionName(Action action) const;
|
||||||
|
QString getStandardPoseName(uint16_t pose);
|
||||||
float getActionState(Action action) const { return _actionStates[toInt(action)]; }
|
float getActionState(Action action) const { return _actionStates[toInt(action)]; }
|
||||||
Pose getPoseState(Action action) const;
|
Pose getPoseState(Action action) const;
|
||||||
int findAction(const QString& actionName) const;
|
int findAction(const QString& actionName) const;
|
||||||
|
|
|
@ -36,9 +36,6 @@ void ActionEndpoint::apply(const Pose& value, const Pointer& source) {
|
||||||
auto userInputMapper = DependencyManager::get<UserInputMapper>();
|
auto userInputMapper = DependencyManager::get<UserInputMapper>();
|
||||||
QString actionName = userInputMapper->getActionName(Action(_input.getChannel()));
|
QString actionName = userInputMapper->getActionName(Action(_input.getChannel()));
|
||||||
inputRecorder->setActionState(actionName, _currentPose);
|
inputRecorder->setActionState(actionName, _currentPose);
|
||||||
if (inputRecorder->isPlayingback()) {
|
|
||||||
_currentPose = inputRecorder->getPoseState(actionName);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_currentPose.isValid()) {
|
if (!_currentPose.isValid()) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -12,6 +12,11 @@
|
||||||
|
|
||||||
#include "../Endpoint.h"
|
#include "../Endpoint.h"
|
||||||
|
|
||||||
|
#include <DependencyManager.h>
|
||||||
|
|
||||||
|
#include "../../InputRecorder.h"
|
||||||
|
#include "../../UserInputMapper.h"
|
||||||
|
|
||||||
namespace controller {
|
namespace controller {
|
||||||
|
|
||||||
class StandardEndpoint : public VirtualEndpoint {
|
class StandardEndpoint : public VirtualEndpoint {
|
||||||
|
@ -40,6 +45,12 @@ public:
|
||||||
|
|
||||||
virtual Pose pose() override {
|
virtual Pose pose() override {
|
||||||
_read = true;
|
_read = true;
|
||||||
|
InputRecorder* inputRecorder = InputRecorder::getInstance();
|
||||||
|
if (inputRecorder->isPlayingback()) {
|
||||||
|
auto userInputMapper = DependencyManager::get<UserInputMapper>();
|
||||||
|
QString actionName = userInputMapper->getStandardPoseName(_input.getChannel());
|
||||||
|
return inputRecorder->getPoseState(actionName);
|
||||||
|
}
|
||||||
return VirtualEndpoint::pose();
|
return VirtualEndpoint::pose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue