From 18ff49744368e23cb743137cf282d2123a61880b Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 12 Aug 2014 16:11:53 -0700 Subject: [PATCH] Added all relevant curves to RecordingFrames --- interface/src/Recorder.cpp | 208 ++++++++++++++++++++++++++++++++++--- interface/src/Recorder.h | 56 +++++++++- 2 files changed, 248 insertions(+), 16 deletions(-) diff --git a/interface/src/Recorder.cpp b/interface/src/Recorder.cpp index 87352fed98..c15e17597e 100644 --- a/interface/src/Recorder.cpp +++ b/interface/src/Recorder.cpp @@ -9,6 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include + #include "Recorder.h" void RecordingFrame::setBlendshapeCoefficients(QVector blendshapeCoefficients) { @@ -23,6 +25,34 @@ void RecordingFrame::setTranslation(glm::vec3 translation) { _translation = translation; } +void RecordingFrame::setRotation(glm::quat rotation) { + _rotation = rotation; +} + +void RecordingFrame::setScale(float scale) { + _scale = scale; +} + +void RecordingFrame::setHeadRotation(glm::quat headRotation) { + _headRotation = headRotation; +} + +void RecordingFrame::setLeanSideways(float leanSideways) { + _leanSideways = leanSideways; +} + +void RecordingFrame::setLeanForward(float leanForward) { + _leanForward = leanForward; +} + +void RecordingFrame::setEstimatedEyePitch(float estimatedEyePitch) { + _estimatedEyePitch = estimatedEyePitch; +} + +void RecordingFrame::setEstimatedEyeYaw(float estimatedEyeYaw) { + _estimatedEyeYaw = estimatedEyeYaw; +} + void Recording::addFrame(int timestamp, RecordingFrame &frame) { _timestamps << timestamp; _frames << frame; @@ -33,7 +63,10 @@ void Recording::clear() { _frames.clear(); } -Recorder::Recorder(AvatarData* avatar) : _avatar(avatar) { +Recorder::Recorder(AvatarData* avatar) : + _recording(new Recording()), + _avatar(avatar) +{ } bool Recorder::isRecording() const { @@ -49,29 +82,72 @@ qint64 Recorder::elapsed() const { } void Recorder::startRecording() { - _recording.clear(); + qDebug() << "Recorder::startRecording()"; + _recording->clear(); _timer.start(); + + RecordingFrame frame; + frame.setBlendshapeCoefficients(_avatar->getHeadData()->getBlendshapeCoefficients()); + frame.setJointRotations(_avatar->getJointRotations()); + frame.setTranslation(_avatar->getPosition()); + frame.setRotation(_avatar->getOrientation()); + frame.setScale(_avatar->getTargetScale()); + + // TODO + const HeadData* head = _avatar->getHeadData(); + glm::quat rotation = glm::quat(glm::radians(glm::vec3(head->getFinalPitch(), + head->getFinalYaw(), + head->getFinalRoll()))); + frame.setHeadRotation(rotation); + // TODO + //frame.setEstimatedEyePitch(); + //frame.setEstimatedEyeYaw(); + + _recording->addFrame(0, frame); } void Recorder::stopRecording() { + qDebug() << "Recorder::stopRecording()"; _timer.invalidate(); + + qDebug().nospace() << "Recorded " << _recording->getFrameNumber() << " during " << _recording->getLength() << " msec (" << _recording->getFrameNumber() / (_recording->getLength() / 1000.0f) << " fps)"; } void Recorder::saveToFile(QString file) { - if (_recording.isEmpty()) { + if (_recording->isEmpty()) { qDebug() << "Cannot save recording to file, recording is empty."; } - writeRecordingToFile(_recording, file); + writeRecordingToFile(*_recording, file); } void Recorder::record() { - qDebug() << "Recording " << _avatar; - RecordingFrame frame; - frame.setBlendshapeCoefficients(_avatar->_) + if (isRecording()) { + const RecordingFrame& referenceFrame = _recording->getFrame(0); + RecordingFrame frame; + frame.setBlendshapeCoefficients(_avatar->getHeadData()->getBlendshapeCoefficients()); + frame.setJointRotations(_avatar->getJointRotations()); + frame.setTranslation(_avatar->getPosition() - referenceFrame.getTranslation()); + frame.setRotation(glm::inverse(referenceFrame.getRotation()) * _avatar->getOrientation()); + frame.setScale(_avatar->getTargetScale() / referenceFrame.getScale()); + // TODO + //frame.setHeadTranslation(); + const HeadData* head = _avatar->getHeadData(); + glm::quat rotation = glm::quat(glm::radians(glm::vec3(head->getFinalPitch(), + head->getFinalYaw(), + head->getFinalRoll()))); + frame.setHeadRotation(glm::inverse(referenceFrame.getHeadRotation()) * rotation); + // TODO + //frame.setEstimatedEyePitch(); + //frame.setEstimatedEyeYaw(); + _recording->addFrame(_timer.elapsed(), frame); + } } -Player::Player(AvatarData* avatar) : _avatar(avatar) { +Player::Player(AvatarData* avatar) : + _recording(new Recording()), + _avatar(avatar) +{ } bool Player::isPlaying() const { @@ -86,21 +162,129 @@ qint64 Player::elapsed() const { } } +QVector Player::getBlendshapeCoefficients() { + computeCurrentFrame(); + return _recording->getFrame(_currentFrame).getBlendshapeCoefficients(); +} + +QVector Player::getJointRotations() { + computeCurrentFrame(); + return _recording->getFrame(_currentFrame).getJointRotations(); +} + +glm::quat Player::getRotation() { + computeCurrentFrame(); + return _recording->getFrame(_currentFrame).getRotation(); +} + +float Player::getScale() { + computeCurrentFrame(); + return _recording->getFrame(_currentFrame).getScale(); +} + +glm::quat Player::getHeadRotation() { + computeCurrentFrame(); + if (_currentFrame >= 0 && _currentFrame <= _recording->getFrameNumber()) { + if (_currentFrame == _recording->getFrameNumber()) { + return _recording->getFrame(0).getHeadRotation() * + _recording->getFrame(_currentFrame - 1).getHeadRotation(); + } + if (_currentFrame == 0) { + return _recording->getFrame(_currentFrame).getHeadRotation(); + } + + return _recording->getFrame(0).getHeadRotation() * + _recording->getFrame(_currentFrame).getHeadRotation(); + } + qWarning() << "Incorrect use of Player::getHeadRotation()"; + return glm::quat(); +} + +float Player::getEstimatedEyePitch() { + computeCurrentFrame(); + return _recording->getFrame(_currentFrame).getEstimatedEyePitch(); +} + +float Player::getEstimatedEyeYaw() { + computeCurrentFrame(); + return _recording->getFrame(_currentFrame).getEstimatedEyeYaw(); +} + + void Player::startPlaying() { - _timer.start(); + if (_recording && _recording->getFrameNumber() > 0) { + qDebug() << "Recorder::startPlaying()"; + _timer.start(); + _currentFrame = 0; + } } void Player::stopPlaying() { + qDebug() << "Recorder::stopPlaying()"; _timer.invalidate(); } void Player::loadFromFile(QString file) { - _recording.clear(); - readRecordingFromFile(_recording, file); + if (_recording) { + _recording->clear(); + } else { + _recording = RecordingPointer(new Recording()); + } + readRecordingFromFile(*_recording, file); +} + +void Player::loadRecording(RecordingPointer recording) { + _recording = recording; } void Player::play() { - qDebug() << "Playing " << _avatar; + qDebug() << "Playing " << _timer.elapsed() / 1000.0f; + computeCurrentFrame(); + if (_currentFrame < 0 || _currentFrame >= _recording->getFrameNumber()) { + // If it's the end of the recording, stop playing + stopPlaying(); + return; + } + if (_currentFrame == 0) { + _avatar->setPosition(_recording->getFrame(_currentFrame).getTranslation()); + _avatar->setOrientation(_recording->getFrame(_currentFrame).getRotation()); + _avatar->setTargetScale(_recording->getFrame(_currentFrame).getScale()); + HeadData* head = const_cast(_avatar->getHeadData()); + head->setBlendshapeCoefficients(_recording->getFrame(_currentFrame).getBlendshapeCoefficients()); + // TODO + // HEAD: Coeff, Translation, estimated eye rotations + // BODY: Joint Rotations + } else { + _avatar->setPosition(_recording->getFrame(0).getTranslation() + + _recording->getFrame(_currentFrame).getTranslation()); + _avatar->setOrientation(_recording->getFrame(0).getRotation() * + _recording->getFrame(_currentFrame).getRotation()); + _avatar->setTargetScale(_recording->getFrame(0).getScale() * + _recording->getFrame(_currentFrame).getScale()); + HeadData* head = const_cast(_avatar->getHeadData()); + head->setBlendshapeCoefficients(_recording->getFrame(_currentFrame).getBlendshapeCoefficients()); + // TODO + // HEAD: Coeff, Translation, estimated eye rotations + // BODY: Joint Rotations + } +} + +void Player::computeCurrentFrame() { + if (!isPlaying()) { + qDebug() << "Not Playing"; + _currentFrame = -1; + return; + } + if (_currentFrame < 0) { + qDebug() << "Reset to 0"; + _currentFrame = 0; + } + + while (_currentFrame < _recording->getFrameNumber() && + _recording->getFrameTimestamp(_currentFrame) < _timer.elapsed()) { + qDebug() << "Loop"; + ++_currentFrame; + } } void writeRecordingToFile(Recording& recording, QString file) { diff --git a/interface/src/Recorder.h b/interface/src/Recorder.h index 2d32e4a9b0..798e3f5ba8 100644 --- a/interface/src/Recorder.h +++ b/interface/src/Recorder.h @@ -15,7 +15,9 @@ #include #include #include +#include #include +#include #include #include @@ -23,7 +25,15 @@ #include #include +class Recorder; class Recording; +class Player; + +typedef QSharedPointer RecordingPointer; +typedef QSharedPointer RecorderPointer; +typedef QWeakPointer WeakRecorderPointer; +typedef QSharedPointer PlayerPointer; +typedef QWeakPointer WeakPlayerPointer; /// Stores the different values associated to one recording frame class RecordingFrame { @@ -31,20 +41,41 @@ public: QVector getBlendshapeCoefficients() const { return _blendshapeCoefficients; } QVector getJointRotations() const { return _jointRotations; } glm::vec3 getTranslation() const { return _translation; } + glm::quat getRotation() const { return _rotation; } + float getScale() const { return _scale; } + glm::quat getHeadRotation() const { return _headRotation; } + float getLeanSideways() const { return _leanSideways; } + float getLeanForward() const { return _leanForward; } + float getEstimatedEyePitch() const { return _estimatedEyePitch; } + float getEstimatedEyeYaw() const { return _estimatedEyeYaw; } protected: void setBlendshapeCoefficients(QVector blendshapeCoefficients); void setJointRotations(QVector jointRotations); void setTranslation(glm::vec3 translation); + void setRotation(glm::quat rotation); + void setScale(float scale); + void setHeadRotation(glm::quat headRotation); + void setLeanSideways(float leanSideways); + void setLeanForward(float leanForward); + void setEstimatedEyePitch(float estimatedEyePitch); + void setEstimatedEyeYaw(float estimatedEyeYaw); private: QVector _blendshapeCoefficients; QVector _jointRotations; glm::vec3 _translation; + glm::quat _rotation; + float _scale; + glm::quat _headRotation; + float _leanSideways; + float _leanForward; + float _estimatedEyePitch; + float _estimatedEyeYaw; friend class Recorder; friend void writeRecordingToFile(Recording& recording, QString file); - friend Recording* readRecordingFromFile(QString file); + friend RecordingPointer readRecordingFromFile(QString file); }; /// Stores a recording @@ -52,6 +83,7 @@ class Recording { public: bool isEmpty() const { return _timestamps.isEmpty(); } int getLength() const { return _timestamps.last(); } // in ms + int getFrameNumber() const { return _frames.size(); } qint32 getFrameTimestamp(int i) const { return _timestamps[i]; } const RecordingFrame& getFrame(int i) const { return _frames[i]; } @@ -67,7 +99,7 @@ private: friend class Recorder; friend class Player; friend void writeRecordingToFile(Recording& recording, QString file); - friend Recording* readRecordingFromFile(QString file); + friend RecordingPointer readRecordingFromFile(QString file); }; @@ -79,6 +111,8 @@ public: bool isRecording() const; qint64 elapsed() const; + RecordingPointer getRecording() const { return _recording; } + public slots: void startRecording(); void stopRecording(); @@ -87,7 +121,7 @@ public slots: private: QElapsedTimer _timer; - Recording _recording; + RecordingPointer _recording; AvatarData* _avatar; }; @@ -100,15 +134,29 @@ public: bool isPlaying() const; qint64 elapsed() const; + // Those should only be called if isPlaying() returns true + QVector getBlendshapeCoefficients(); + QVector getJointRotations(); + glm::quat getRotation(); + float getScale(); + glm::vec3 getHeadTranslation(); + glm::quat getHeadRotation(); + float getEstimatedEyePitch(); + float getEstimatedEyeYaw(); + public slots: void startPlaying(); void stopPlaying(); void loadFromFile(QString file); + void loadRecording(RecordingPointer recording); void play(); private: + void computeCurrentFrame(); + QElapsedTimer _timer; - Recording _recording; + RecordingPointer _recording; + int _currentFrame; AvatarData* _avatar; };