From 117a868bcf5d1a4413a2a93b3de0ee590fadd915 Mon Sep 17 00:00:00 2001 From: Craig Hansen-Sturm Date: Mon, 15 Sep 2014 17:49:48 -0700 Subject: [PATCH 01/23] head penumbra filter tuning with Freddy / filter defaults to on --- assignment-client/src/audio/AudioMixer.cpp | 34 +++++++++---------- .../resources/web/settings/describe.json | 2 +- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index bfe2f7e249..714cd0e3f3 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -321,9 +321,14 @@ int AudioMixer::addStreamToMixForListeningNodeWithStream(PositionalAudioStream* const float TWO_OVER_PI = 2.0f / PI; const float ZERO_DB = 1.0f; - const float NEGATIVE_ONE_DB = 0.891f; +// const float NEGATIVE_ONE_DB = 0.891f; const float NEGATIVE_THREE_DB = 0.708f; - + const float NEGATIVE_SIX_DB = 0.501f; + + const float FILTER_GAIN_AT_0 = ZERO_DB; // source is in front + const float FILTER_GAIN_AT_90 = NEGATIVE_SIX_DB; // source is incident to left or right ear + const float FILTER_GAIN_AT_180 = NEGATIVE_SIX_DB; // source is behind + const float FILTER_CUTOFF_FREQUENCY_HZ = 1000.0f; const float penumbraFilterFrequency = FILTER_CUTOFF_FREQUENCY_HZ; // constant frequency @@ -334,32 +339,25 @@ int AudioMixer::addStreamToMixForListeningNodeWithStream(PositionalAudioStream* // variable gain calculation broken down by quadrent if (bearingAngleToSource < -PI_OVER_TWO && bearingAngleToSource > -PI) { - // gainL(-pi/2,0b)->(-pi,-1db) penumbraFilterGainL = TWO_OVER_PI * - (ZERO_DB - NEGATIVE_ONE_DB) * (bearingAngleToSource + PI_OVER_TWO) + ZERO_DB; - // gainR(-pi/2,-3db)->(-pi,-1db) + (FILTER_GAIN_AT_0 - FILTER_GAIN_AT_180) * (bearingAngleToSource + PI_OVER_TWO) + FILTER_GAIN_AT_0; penumbraFilterGainR = TWO_OVER_PI * - (NEGATIVE_THREE_DB - NEGATIVE_ONE_DB) * (bearingAngleToSource + PI_OVER_TWO) + NEGATIVE_THREE_DB; + (FILTER_GAIN_AT_90 - FILTER_GAIN_AT_180) * (bearingAngleToSource + PI_OVER_TWO) + FILTER_GAIN_AT_90; } else if (bearingAngleToSource <= PI && bearingAngleToSource > PI_OVER_TWO) { - // gainL(+pi,-1db)->(pi/2,-3db) penumbraFilterGainL = TWO_OVER_PI * - (NEGATIVE_ONE_DB - NEGATIVE_THREE_DB) * (bearingAngleToSource - PI) + NEGATIVE_ONE_DB; - // gainR(+pi,-1db)->(pi/2,0db) + (FILTER_GAIN_AT_180 - FILTER_GAIN_AT_90) * (bearingAngleToSource - PI) + FILTER_GAIN_AT_180; penumbraFilterGainR = TWO_OVER_PI * - (NEGATIVE_ONE_DB - ZERO_DB) * (bearingAngleToSource - PI) + NEGATIVE_ONE_DB; + (FILTER_GAIN_AT_180 - FILTER_GAIN_AT_0) * (bearingAngleToSource - PI) + FILTER_GAIN_AT_180; } else if (bearingAngleToSource <= PI_OVER_TWO && bearingAngleToSource > 0) { - // gainL(+pi/2,-3db)->(0,0db) penumbraFilterGainL = TWO_OVER_PI * - (NEGATIVE_THREE_DB - ZERO_DB) * (bearingAngleToSource - PI_OVER_TWO) + NEGATIVE_THREE_DB; - // gainR(+p1/2,0db)->(0,0db) - penumbraFilterGainR = ZERO_DB; + (FILTER_GAIN_AT_90 - FILTER_GAIN_AT_0) * (bearingAngleToSource - PI_OVER_TWO) + FILTER_GAIN_AT_90; + penumbraFilterGainR = FILTER_GAIN_AT_0; } else { - // gainL(0,0db)->(-pi/2,0db) - penumbraFilterGainL = ZERO_DB; - // gainR(0,0db)->(-pi/2,-3db) + penumbraFilterGainL = FILTER_GAIN_AT_0; penumbraFilterGainR = TWO_OVER_PI * - (ZERO_DB - NEGATIVE_THREE_DB) * (bearingAngleToSource) + ZERO_DB; + (FILTER_GAIN_AT_0 - FILTER_GAIN_AT_90) * (bearingAngleToSource) + FILTER_GAIN_AT_0; } + #if 0 qDebug() << "avatar=" << listeningNodeStream diff --git a/domain-server/resources/web/settings/describe.json b/domain-server/resources/web/settings/describe.json index fee7ff21fc..2ea0aec0c7 100644 --- a/domain-server/resources/web/settings/describe.json +++ b/domain-server/resources/web/settings/describe.json @@ -67,7 +67,7 @@ "type": "checkbox", "label": "Enable Positional Filter", "help": "If enabled, positional audio stream uses lowpass filter", - "default": false + "default": true } } } From dbcb778ea9d84d242640ab09a4ae0a79f8c04c77 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Thu, 18 Sep 2014 08:33:41 -0700 Subject: [PATCH 02/23] Drive mouth with loudness relative to long term average --- examples/headMove.js | 2 +- interface/src/avatar/Head.cpp | 22 ++++++++++++++++------ interface/src/avatar/Head.h | 1 + 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/examples/headMove.js b/examples/headMove.js index 0a7686c569..f8a1895a08 100644 --- a/examples/headMove.js +++ b/examples/headMove.js @@ -79,7 +79,7 @@ function moveWithHead(deltaTime) { if (Math.abs(headDelta.z) > HEAD_MOVE_DEAD_ZONE) { if (Math.abs(Vec3.dot(velocity, forward)) < maxVelocity) { thrust = Vec3.sum(thrust, Vec3.multiply(forward, -headDelta.z * HEAD_THRUST_FWD_SCALE * deltaTime)); - } + } } if (Math.abs(headDelta.x) > HEAD_STRAFE_DEAD_ZONE) { if (Math.abs(Vec3.dot(velocity, right)) < maxVelocity) { diff --git a/interface/src/avatar/Head.cpp b/interface/src/avatar/Head.cpp index b226b8ed31..d1fcc0f33f 100644 --- a/interface/src/avatar/Head.cpp +++ b/interface/src/avatar/Head.cpp @@ -32,6 +32,7 @@ Head::Head(Avatar* owningAvatar) : _eyePosition(0.0f, 0.0f, 0.0f), _scale(1.0f), _lastLoudness(0.0f), + _longTermAverageLoudness(-1.0f), _audioAttack(0.0f), _angularVelocity(0,0,0), _renderLookatVectors(false), @@ -62,7 +63,7 @@ void Head::reset() { } void Head::simulate(float deltaTime, bool isMine, bool billboard) { - // Update audio trailing average for rendering facial animations + if (isMine) { MyAvatar* myAvatar = static_cast(_owningAvatar); @@ -78,6 +79,18 @@ void Head::simulate(float deltaTime, bool isMine, bool billboard) { } } } + // Update audio trailing average for rendering facial animations + const float AUDIO_AVERAGING_SECS = 0.05f; + const float AUDIO_LONG_TERM_AVERAGING_SECS = 30.f; + _averageLoudness = glm::mix(_averageLoudness, _audioLoudness, glm::min(deltaTime / AUDIO_AVERAGING_SECS, 1.0f)); + + if (_longTermAverageLoudness == -1.0) { + _longTermAverageLoudness = _averageLoudness; + } else { + _longTermAverageLoudness = glm::mix(_longTermAverageLoudness, _averageLoudness, glm::min(deltaTime / AUDIO_LONG_TERM_AVERAGING_SECS, 1.0f)); + } + float deltaLoudness = glm::max(0.0f, _averageLoudness - _longTermAverageLoudness); + qDebug() << "deltaLoudness: " << deltaLoudness; if (!(_isFaceshiftConnected || billboard)) { // Update eye saccades @@ -92,9 +105,6 @@ void Head::simulate(float deltaTime, bool isMine, bool billboard) { _saccadeTarget = SACCADE_MAGNITUDE * randVector(); } _saccade += (_saccadeTarget - _saccade) * 0.50f; - - const float AUDIO_AVERAGING_SECS = 0.05f; - _averageLoudness = glm::mix(_averageLoudness, _audioLoudness, glm::min(deltaTime / AUDIO_AVERAGING_SECS, 1.0f)); // Detect transition from talking to not; force blink after that and a delay bool forceBlink = false; @@ -108,8 +118,8 @@ void Head::simulate(float deltaTime, bool isMine, bool billboard) { } // Update audio attack data for facial animation (eyebrows and mouth) - _audioAttack = 0.9f * _audioAttack + 0.1f * fabs(_audioLoudness - _lastLoudness); - _lastLoudness = _audioLoudness; + _audioAttack = 0.9f * _audioAttack + 0.1f * fabs((_audioLoudness - _longTermAverageLoudness) - _lastLoudness); + _lastLoudness = (_audioLoudness - _longTermAverageLoudness); const float BROW_LIFT_THRESHOLD = 100.0f; if (_audioAttack > BROW_LIFT_THRESHOLD) { diff --git a/interface/src/avatar/Head.h b/interface/src/avatar/Head.h index 1cdfdaf5a3..e99a7f5c7b 100644 --- a/interface/src/avatar/Head.h +++ b/interface/src/avatar/Head.h @@ -121,6 +121,7 @@ private: float _scale; float _lastLoudness; + float _longTermAverageLoudness; float _audioAttack; glm::vec3 _angularVelocity; bool _renderLookatVectors; From 7e7c4bd5804682e8f977abec64d5e8cbc3c8a313 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 18 Sep 2014 10:09:57 -0700 Subject: [PATCH 03/23] handle hifi urls emitted from DataWebDialog --- interface/src/ui/DataWebDialog.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/interface/src/ui/DataWebDialog.cpp b/interface/src/ui/DataWebDialog.cpp index 9914383220..9a67da48a8 100644 --- a/interface/src/ui/DataWebDialog.cpp +++ b/interface/src/ui/DataWebDialog.cpp @@ -15,6 +15,8 @@ #include #include +#include "Application.h" + #include "DataWebDialog.h" DataWebDialog::DataWebDialog() { @@ -23,6 +25,12 @@ DataWebDialog::DataWebDialog() { // use an OAuthNetworkAccessManager instead of regular QNetworkAccessManager so our requests are authed page()->setNetworkAccessManager(OAuthNetworkAccessManager::getInstance()); + + // have the page delete external links so they can be captured by the Application in case they are a hifi link + page()->setLinkDelegationPolicy(QWebPage::DelegateExternalLinks); + + // have the Application handle external links + connect(this, &QWebView::linkClicked, Application::getInstance(), &Application::openUrl); } DataWebDialog* DataWebDialog::dialogForPath(const QString& path) { From 533a60c35e65c1d8ec78efcc888aeb6654a3821c Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 18 Sep 2014 10:34:17 -0700 Subject: [PATCH 04/23] make sure OAuthWebViewHandler is ready before the NodeList is --- interface/src/Application.cpp | 9 ++++----- interface/src/ui/OAuthWebViewHandler.cpp | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 44fc8d7cec..a20a6553d4 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -219,6 +219,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : if (portStr) { listenPort = atoi(portStr); } + + // call the OAuthWebviewHandler static getter so that its instance lives in our thread + // make sure it is ready before the NodeList might need it + OAuthWebViewHandler::getInstance(); // start the nodeThread so its event loop is running _nodeThread->start(); @@ -418,11 +422,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : connect(_window, &MainWindow::windowGeometryChanged, _runningScriptsWidget, &RunningScriptsWidget::setBoundary); - // call the OAuthWebviewHandler static getter so that its instance lives in our thread - OAuthWebViewHandler::getInstance(); - // make sure the High Fidelity root CA is in our list of trusted certs - OAuthWebViewHandler::addHighFidelityRootCAToSSLConfig(); - _trayIcon->show(); #ifdef HAVE_RTMIDI diff --git a/interface/src/ui/OAuthWebViewHandler.cpp b/interface/src/ui/OAuthWebViewHandler.cpp index a1dbfe9e0b..4cc5af07a6 100644 --- a/interface/src/ui/OAuthWebViewHandler.cpp +++ b/interface/src/ui/OAuthWebViewHandler.cpp @@ -27,7 +27,7 @@ OAuthWebViewHandler::OAuthWebViewHandler() : _webViewRedisplayTimer(), _lastAuthorizationURL() { - + addHighFidelityRootCAToSSLConfig(); } const char HIGH_FIDELITY_CA[] = "-----BEGIN CERTIFICATE-----\n" From 397be962f4ff59bd43c5b9a0663cf995492d1e01 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 18 Sep 2014 10:37:36 -0700 Subject: [PATCH 05/23] CR fixes --- libraries/avatars/src/Player.cpp | 21 ++++++++++----------- libraries/avatars/src/Player.h | 4 ++-- libraries/avatars/src/Recorder.cpp | 2 +- libraries/avatars/src/Recorder.h | 2 +- libraries/avatars/src/Recording.cpp | 12 ++++++------ libraries/avatars/src/Recording.h | 22 +++++++++++----------- 6 files changed, 31 insertions(+), 32 deletions(-) diff --git a/libraries/avatars/src/Player.cpp b/libraries/avatars/src/Player.cpp index f18c7f04aa..3b74ce595a 100644 --- a/libraries/avatars/src/Player.cpp +++ b/libraries/avatars/src/Player.cpp @@ -17,15 +17,15 @@ #include "Player.h" Player::Player(AvatarData* avatar) : -_recording(new Recording()), -_avatar(avatar), -_audioThread(NULL), -_playFromCurrentPosition(true), -_loop(false), -_useAttachments(true), -_useDisplayName(true), -_useHeadURL(true), -_useSkeletonURL(true) + _recording(new Recording()), + _avatar(avatar), + _audioThread(NULL), + _playFromCurrentPosition(true), + _loop(false), + _useAttachments(true), + _useDisplayName(true), + _useHeadURL(true), + _useSkeletonURL(true) { _timer.invalidate(); _options.setLoop(false); @@ -157,10 +157,9 @@ void Player::loopRecording() { setupAudioThread(); _currentFrame = 0; _timer.restart(); - } -void Player::loadFromFile(QString file) { +void Player::loadFromFile(QString& file) { if (_recording) { _recording->clear(); } else { diff --git a/libraries/avatars/src/Player.h b/libraries/avatars/src/Player.h index ba2ab9951a..bf8aed8576 100644 --- a/libraries/avatars/src/Player.h +++ b/libraries/avatars/src/Player.h @@ -34,10 +34,10 @@ public: RecordingPointer getRecording() const { return _recording; } - public slots: +public slots: void startPlaying(); void stopPlaying(); - void loadFromFile(QString file); + void loadFromFile(QString& file); void loadRecording(RecordingPointer recording); void play(); diff --git a/libraries/avatars/src/Recorder.cpp b/libraries/avatars/src/Recorder.cpp index 4c71dc1a18..5d966e34fb 100644 --- a/libraries/avatars/src/Recorder.cpp +++ b/libraries/avatars/src/Recorder.cpp @@ -86,7 +86,7 @@ void Recorder::stopRecording() { qDebug().nospace() << "Recorded " << _recording->getFrameNumber() << " during " << _recording->getLength() << " msec (" << _recording->getFrameNumber() / (_recording->getLength() / 1000.0f) << " fps)"; } -void Recorder::saveToFile(QString file) { +void Recorder::saveToFile(QString& file) { if (_recording->isEmpty()) { qDebug() << "Cannot save recording to file, recording is empty."; } diff --git a/libraries/avatars/src/Recorder.h b/libraries/avatars/src/Recorder.h index 454e8016fa..8534541b6c 100644 --- a/libraries/avatars/src/Recorder.h +++ b/libraries/avatars/src/Recorder.h @@ -38,7 +38,7 @@ public: public slots: void startRecording(); void stopRecording(); - void saveToFile(QString file); + void saveToFile(QString& file); void record(); void record(char* samples, int size); diff --git a/libraries/avatars/src/Recording.cpp b/libraries/avatars/src/Recording.cpp index 63f37a6885..2af1cd3acf 100644 --- a/libraries/avatars/src/Recording.cpp +++ b/libraries/avatars/src/Recording.cpp @@ -74,7 +74,7 @@ void Recording::addFrame(int timestamp, RecordingFrame &frame) { _frames << frame; } -void Recording::addAudioPacket(QByteArray byteArray) { +void Recording::addAudioPacket(QByteArray& byteArray) { if (!_audio) { _audio = new Sound(byteArray); return; @@ -89,7 +89,7 @@ void Recording::clear() { _audio = NULL; } -void writeVec3(QDataStream& stream, glm::vec3 value) { +void writeVec3(QDataStream& stream, glm::vec3& value) { unsigned char buffer[sizeof(value)]; memcpy(buffer, &value, sizeof(value)); stream.writeRawData(reinterpret_cast(buffer), sizeof(value)); @@ -102,7 +102,7 @@ bool readVec3(QDataStream& stream, glm::vec3& value) { return true; } -void writeQuat(QDataStream& stream, glm::quat value) { +void writeQuat(QDataStream& stream, glm::quat& value) { unsigned char buffer[256]; int writtenToBuffer = packOrientationQuatToBytes(buffer, value); stream.writeRawData(reinterpret_cast(buffer), writtenToBuffer); @@ -136,7 +136,7 @@ bool readFloat(QDataStream& stream, float& value, int radix) { return true; } -void writeRecordingToFile(RecordingPointer recording, QString filename) { +void writeRecordingToFile(RecordingPointer recording, QString& filename) { if (!recording || recording->getFrameNumber() < 1) { qDebug() << "Can't save empty recording"; return; @@ -377,7 +377,7 @@ void writeRecordingToFile(RecordingPointer recording, QString filename) { qDebug() << "Wrote" << file.size() << "bytes in" << writtingTime + checksumTime << "ms. (" << checksumTime << "ms for checksum)"; } -RecordingPointer readRecordingFromFile(RecordingPointer recording, QString filename) { +RecordingPointer readRecordingFromFile(RecordingPointer recording, QString& filename) { QByteArray byteArray; QUrl url(filename); QElapsedTimer timer; @@ -641,7 +641,7 @@ RecordingPointer readRecordingFromFile(RecordingPointer recording, QString filen } -RecordingPointer readRecordingFromRecFile(RecordingPointer recording, QString filename, QByteArray byteArray) { +RecordingPointer readRecordingFromRecFile(RecordingPointer recording, QString& filename, QByteArray& byteArray) { QElapsedTimer timer; timer.start(); diff --git a/libraries/avatars/src/Recording.h b/libraries/avatars/src/Recording.h index ddfebaeb5e..e361887d7f 100644 --- a/libraries/avatars/src/Recording.h +++ b/libraries/avatars/src/Recording.h @@ -62,7 +62,7 @@ public: protected: void addFrame(int timestamp, RecordingFrame& frame); - void addAudioPacket(QByteArray byteArray); + void addAudioPacket(QByteArray& byteArray); void clear(); private: @@ -74,9 +74,9 @@ private: friend class Recorder; friend class Player; - friend void writeRecordingToFile(RecordingPointer recording, QString file); - friend RecordingPointer readRecordingFromFile(RecordingPointer recording, QString file); - friend RecordingPointer readRecordingFromRecFile(RecordingPointer recording, QString filename, QByteArray byteArray); + friend void writeRecordingToFile(RecordingPointer recording, QString& file); + friend RecordingPointer readRecordingFromFile(RecordingPointer recording, QString& file); + friend RecordingPointer readRecordingFromRecFile(RecordingPointer recording, QString& filename, QByteArray& byteArray); }; /// Stores the different values associated to one recording frame @@ -101,7 +101,7 @@ protected: void setHeadRotation(glm::quat headRotation) { _headRotation = headRotation; } void setLeanSideways(float leanSideways) { _leanSideways = leanSideways; } void setLeanForward(float leanForward) { _leanForward = leanForward; } - void setLookAtPosition(glm::vec3 lookAtPosition) { _lookAtPosition = lookAtPosition; } + void setLookAtPosition(glm::vec3& lookAtPosition) { _lookAtPosition = lookAtPosition; } private: QVector _blendshapeCoefficients; @@ -115,13 +115,13 @@ private: glm::vec3 _lookAtPosition; friend class Recorder; - friend void writeRecordingToFile(RecordingPointer recording, QString file); - friend RecordingPointer readRecordingFromFile(RecordingPointer recording, QString file); - friend RecordingPointer readRecordingFromRecFile(RecordingPointer recording, QString filename, QByteArray byteArray); + friend void writeRecordingToFile(RecordingPointer recording, QString& file); + friend RecordingPointer readRecordingFromFile(RecordingPointer recording, QString& file); + friend RecordingPointer readRecordingFromRecFile(RecordingPointer recording, QString& filename, QByteArray& byteArray); }; -void writeRecordingToFile(RecordingPointer recording, QString filename); -RecordingPointer readRecordingFromFile(RecordingPointer recording, QString filename); -RecordingPointer readRecordingFromRecFile(RecordingPointer recording, QString filename, QByteArray byteArray); +void writeRecordingToFile(RecordingPointer recording, QString& filename); +RecordingPointer readRecordingFromFile(RecordingPointer recording, QString& filename); +RecordingPointer readRecordingFromRecFile(RecordingPointer recording, QString& filename, QByteArray& byteArray); #endif // hifi_Recording_h \ No newline at end of file From 72d8522adc578dc9fa62a7578d655612e7df6c2c Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 18 Sep 2014 10:45:12 -0700 Subject: [PATCH 06/23] Fixed typo + removed MesageBoxes --- libraries/avatars/src/Recording.cpp | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/libraries/avatars/src/Recording.cpp b/libraries/avatars/src/Recording.cpp index 2af1cd3acf..cc03d23d88 100644 --- a/libraries/avatars/src/Recording.cpp +++ b/libraries/avatars/src/Recording.cpp @@ -20,7 +20,6 @@ #include #include #include -#include #include #include "AvatarData.h" @@ -329,7 +328,7 @@ void writeRecordingToFile(RecordingPointer recording, QString& filename) { fileStream << recording->_audio->getByteArray(); - qint64 writtingTime = timer.restart(); + qint64 writingTime = timer.restart(); // Write data length and CRC-16 quint32 dataLength = file.pos() - dataOffset; file.seek(dataOffset); // Go to beginning of data for checksum @@ -374,7 +373,7 @@ void writeRecordingToFile(RecordingPointer recording, QString& filename) { } qint64 checksumTime = timer.elapsed(); - qDebug() << "Wrote" << file.size() << "bytes in" << writtingTime + checksumTime << "ms. (" << checksumTime << "ms for checksum)"; + qDebug() << "Wrote" << file.size() << "bytes in" << writingTime + checksumTime << "ms. (" << checksumTime << "ms for checksum)"; } RecordingPointer readRecordingFromFile(RecordingPointer recording, QString& filename) { @@ -416,10 +415,6 @@ RecordingPointer readRecordingFromFile(RecordingPointer recording, QString& file if (filename.endsWith(".rec") || filename.endsWith(".REC")) { qDebug() << "Old .rec format"; - QMessageBox::warning(NULL, - QString("Old recording format"), - QString("Converting your file to the new format."), - QMessageBox::Ok); readRecordingFromRecFile(recording, filename, byteArray); return recording; } else if (!filename.endsWith(".hfr") && !filename.endsWith(".HFR")) { @@ -797,10 +792,6 @@ RecordingPointer readRecordingFromRecFile(RecordingPointer recording, QString& f // Set recording to new format writeRecordingToFile(recording, filename); - QMessageBox::warning(NULL, - QString("New recording location"), - QString("The new recording was saved at:\n" + filename), - QMessageBox::Ok); qDebug() << "Recording has been successfully converted at" << filename; return recording; } From 8c71ed3f103b6106438d7633ff35e8cf5fa3eafa Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Thu, 18 Sep 2014 10:48:36 -0700 Subject: [PATCH 07/23] Improving headMove, added JS call for neckPosition --- examples/headMove.js | 29 +++++++++++++++++++++-------- interface/src/avatar/Avatar.cpp | 6 ++++++ interface/src/avatar/Avatar.h | 2 ++ interface/src/avatar/Head.cpp | 2 +- 4 files changed, 30 insertions(+), 9 deletions(-) diff --git a/examples/headMove.js b/examples/headMove.js index 359dfd8751..68a9a7833d 100644 --- a/examples/headMove.js +++ b/examples/headMove.js @@ -45,7 +45,7 @@ var maxVelocity = 1.25; var noFly = true; //var roomLimits = { xMin: 618, xMax: 635.5, zMin: 528, zMax: 552.5 }; -var roomLimits = { xMin: -1, xMax: 0, zMin: 0, zMax: 0 }; +var roomLimits = { xMin: 142.6, xMax: 153.7, zMin: 177.5, zMax: 192.0 }; function isInRoom(position) { var BUFFER = 2.0; @@ -71,19 +71,29 @@ function moveWithHead(deltaTime) { var deltaPitch = MyAvatar.getHeadDeltaPitch() - headStartDeltaPitch; var deltaRoll = MyAvatar.getHeadFinalRoll() - headStartRoll; var velocity = MyAvatar.getVelocity(); - var bodyLocalCurrentHeadVector = Vec3.subtract(MyAvatar.getHeadPosition(), MyAvatar.position); - bodyLocalCurrentHeadVector = Vec3.multiplyQbyV(Quat.angleAxis(-deltaYaw, {x:0, y: 1, z:0}), bodyLocalCurrentHeadVector); + var position = MyAvatar.position; + var neckPosition = MyAvatar.getNeckPosition(); + var bodyLocalCurrentHeadVector = Vec3.subtract(neckPosition, position); + //bodyLocalCurrentHeadVector = Vec3.multiplyQbyV(Quat.inverse(MyAvatar.orientation), bodyLocalCurrentHeadVector); var headDelta = Vec3.subtract(bodyLocalCurrentHeadVector, headStartPosition); - headDelta = Vec3.multiplyQbyV(Quat.inverse(Camera.getOrientation()), headDelta); + //headDelta = Vec3.multiplyQbyV(Quat.inverse(Camera.getOrientation()), headDelta); headDelta.y = 0.0; // Don't respond to any of the vertical component of head motion + if (Vec3.length(headDelta) > 0.005) { + Vec3.print("headDelta = ", headDelta); + Vec3.print("headStartPosition = ", headStartPosition); + Vec3.print("MyAvatar.position = ", position); + Vec3.print("MyAvatar.getNeckPosition() = ", neckPosition); + + } + // Thrust based on leaning forward and side-to-side var targetVelocity = {x:0.0, y:0.0, z:0.0}; if (Math.abs(headDelta.z) > HEAD_MOVE_DEAD_ZONE) { - targetVelocity = Vec3.multiply(zAxis, -headDelta.z * HEAD_VELOCITY_FWD_FACTOR); + targetVelocity = Vec3.multiply(zAxis, headDelta.z * HEAD_VELOCITY_FWD_FACTOR); } if (Math.abs(headDelta.x) > HEAD_STRAFE_DEAD_ZONE) { - var deltaVelocity = Vec3.multiply(xAxis, -headDelta.x * HEAD_VELOCITY_LEFT_FACTOR); + var deltaVelocity = Vec3.multiply(xAxis, headDelta.x * HEAD_VELOCITY_LEFT_FACTOR); targetVelocity = Vec3.sum(targetVelocity, deltaVelocity); } if (Math.abs(deltaYaw) > HEAD_ROTATE_DEAD_ZONE) { @@ -130,7 +140,10 @@ function moveWithHead(deltaTime) { Controller.keyPressEvent.connect(function(event) { if (event.text == "SPACE" && !movingWithHead) { movingWithHead = true; - headStartPosition = Vec3.subtract(MyAvatar.getHeadPosition(), MyAvatar.position); + Vec3.print("getNeckPosition() = ", MyAvatar.getNeckPosition()); + headStartPosition = Vec3.subtract(MyAvatar.getNeckPosition(), MyAvatar.position); + //headStartPosition = Vec3.multiplyQbyV(Quat.inverse(MyAvatar.orientation), headStartPosition); + Vec3.print("First HeadStartPosition = ", headStartPosition); headStartDeltaPitch = MyAvatar.getHeadDeltaPitch(); headStartFinalPitch = MyAvatar.getHeadFinalPitch(); headStartRoll = MyAvatar.getHeadFinalRoll(); @@ -138,7 +151,7 @@ Controller.keyPressEvent.connect(function(event) { // start with disabled motor -- it will be updated shortly MyAvatar.motorTimescale = VERY_LARGE_TIMESCALE; MyAvatar.motorVelocity = {x:0.0, y:0.0, z:0.0}; - MyAvatar.motorReferenceFrame = "camera"; // alternatives are: "avatar" and "world" + MyAvatar.motorReferenceFrame = "avatar"; // alternatives are: "avatar" and "world" } }); diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index b62c744fa2..bd05f7c4c0 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -97,6 +97,12 @@ glm::vec3 Avatar::getChestPosition() const { return _skeletonModel.getNeckPosition(neckPosition) ? (_position + neckPosition) * 0.5f : _position; } +glm::vec3 Avatar::getNeckPosition() const { + glm::vec3 neckPosition; + return _skeletonModel.getNeckPosition(neckPosition) ? neckPosition : _position; +} + + glm::quat Avatar::getWorldAlignedOrientation () const { return computeRotationFromBodyToWorldUp() * getOrientation(); } diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 921722504d..c449a0d1b9 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -154,6 +154,8 @@ public: Q_INVOKABLE void setJointModelPositionAndOrientation(int index, const glm::vec3 position, const glm::quat& rotation); Q_INVOKABLE void setJointModelPositionAndOrientation(const QString& name, const glm::vec3 position, const glm::quat& rotation); + + Q_INVOKABLE glm::vec3 getNeckPosition() const; Q_INVOKABLE glm::vec3 getVelocity() const { return _velocity; } Q_INVOKABLE glm::vec3 getAcceleration() const { return _acceleration; } diff --git a/interface/src/avatar/Head.cpp b/interface/src/avatar/Head.cpp index 3f0770428b..4c394377a3 100644 --- a/interface/src/avatar/Head.cpp +++ b/interface/src/avatar/Head.cpp @@ -90,7 +90,7 @@ void Head::simulate(float deltaTime, bool isMine, bool billboard) { _longTermAverageLoudness = glm::mix(_longTermAverageLoudness, _averageLoudness, glm::min(deltaTime / AUDIO_LONG_TERM_AVERAGING_SECS, 1.0f)); } float deltaLoudness = glm::max(0.0f, _averageLoudness - _longTermAverageLoudness); - qDebug() << "deltaLoudness: " << deltaLoudness; + //qDebug() << "deltaLoudness: " << deltaLoudness; if (!(_isFaceshiftConnected || billboard)) { // Update eye saccades From ac588a569e570063233d21053f539ace6e8ec64d Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 18 Sep 2014 11:12:11 -0700 Subject: [PATCH 08/23] add const to recording methods where arguments are passed by reference --- libraries/avatars/src/Player.h | 2 +- libraries/avatars/src/Recorder.h | 2 +- libraries/avatars/src/Recording.cpp | 12 ++++++------ libraries/avatars/src/Recording.h | 20 ++++++++++---------- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/libraries/avatars/src/Player.h b/libraries/avatars/src/Player.h index bf8aed8576..772209d435 100644 --- a/libraries/avatars/src/Player.h +++ b/libraries/avatars/src/Player.h @@ -37,7 +37,7 @@ public: public slots: void startPlaying(); void stopPlaying(); - void loadFromFile(QString& file); + void loadFromFile(const QString& file); void loadRecording(RecordingPointer recording); void play(); diff --git a/libraries/avatars/src/Recorder.h b/libraries/avatars/src/Recorder.h index 8534541b6c..e03218287d 100644 --- a/libraries/avatars/src/Recorder.h +++ b/libraries/avatars/src/Recorder.h @@ -38,7 +38,7 @@ public: public slots: void startRecording(); void stopRecording(); - void saveToFile(QString& file); + void saveToFile(const QString& file); void record(); void record(char* samples, int size); diff --git a/libraries/avatars/src/Recording.cpp b/libraries/avatars/src/Recording.cpp index 3afc6b5526..0bc323a8f7 100644 --- a/libraries/avatars/src/Recording.cpp +++ b/libraries/avatars/src/Recording.cpp @@ -73,7 +73,7 @@ void Recording::addFrame(int timestamp, RecordingFrame &frame) { _frames << frame; } -void Recording::addAudioPacket(QByteArray& byteArray) { +void Recording::addAudioPacket(const QByteArray& byteArray) { if (!_audio) { _audio = new Sound(byteArray); return; @@ -88,7 +88,7 @@ void Recording::clear() { _audio = NULL; } -void writeVec3(QDataStream& stream, glm::vec3& value) { +void writeVec3(QDataStream& stream, const glm::vec3& value) { unsigned char buffer[sizeof(value)]; memcpy(buffer, &value, sizeof(value)); stream.writeRawData(reinterpret_cast(buffer), sizeof(value)); @@ -101,7 +101,7 @@ bool readVec3(QDataStream& stream, glm::vec3& value) { return true; } -void writeQuat(QDataStream& stream, glm::quat& value) { +void writeQuat(QDataStream& stream, const glm::quat& value) { unsigned char buffer[256]; int writtenToBuffer = packOrientationQuatToBytes(buffer, value); stream.writeRawData(reinterpret_cast(buffer), writtenToBuffer); @@ -135,7 +135,7 @@ bool readFloat(QDataStream& stream, float& value, int radix) { return true; } -void writeRecordingToFile(RecordingPointer recording, QString& filename) { +void writeRecordingToFile(RecordingPointer recording, const QString& filename) { if (!recording || recording->getFrameNumber() < 1) { qDebug() << "Can't save empty recording"; return; @@ -376,7 +376,7 @@ void writeRecordingToFile(RecordingPointer recording, QString& filename) { qDebug() << "Wrote" << file.size() << "bytes in" << writingTime + checksumTime << "ms. (" << checksumTime << "ms for checksum)"; } -RecordingPointer readRecordingFromFile(RecordingPointer recording, QString& filename) { +RecordingPointer readRecordingFromFile(RecordingPointer recording, const QString& filename) { QByteArray byteArray; QUrl url(filename); QElapsedTimer timer; @@ -636,7 +636,7 @@ RecordingPointer readRecordingFromFile(RecordingPointer recording, QString& file } -RecordingPointer readRecordingFromRecFile(RecordingPointer recording, QString& filename, QByteArray& byteArray) { +RecordingPointer readRecordingFromRecFile(RecordingPointer recording, const QString& filename, const QByteArray& byteArray) { QElapsedTimer timer; timer.start(); diff --git a/libraries/avatars/src/Recording.h b/libraries/avatars/src/Recording.h index e361887d7f..bffa923ed0 100644 --- a/libraries/avatars/src/Recording.h +++ b/libraries/avatars/src/Recording.h @@ -62,7 +62,7 @@ public: protected: void addFrame(int timestamp, RecordingFrame& frame); - void addAudioPacket(QByteArray& byteArray); + void addAudioPacket(const QByteArray& byteArray); void clear(); private: @@ -74,9 +74,9 @@ private: friend class Recorder; friend class Player; - friend void writeRecordingToFile(RecordingPointer recording, QString& file); - friend RecordingPointer readRecordingFromFile(RecordingPointer recording, QString& file); - friend RecordingPointer readRecordingFromRecFile(RecordingPointer recording, QString& filename, QByteArray& byteArray); + friend void writeRecordingToFile(RecordingPointer recording, const QString& file); + friend RecordingPointer readRecordingFromFile(RecordingPointer recording, const QString& file); + friend RecordingPointer readRecordingFromRecFile(RecordingPointer recording, const QString& filename, const QByteArray& byteArray); }; /// Stores the different values associated to one recording frame @@ -95,13 +95,13 @@ public: protected: void setBlendshapeCoefficients(QVector blendshapeCoefficients); void setJointRotations(QVector jointRotations) { _jointRotations = jointRotations; } - void setTranslation(glm::vec3 translation) { _translation = translation; } - void setRotation(glm::quat rotation) { _rotation = rotation; } + void setTranslation(const glm::vec3& translation) { _translation = translation; } + void setRotation(const glm::quat& rotation) { _rotation = rotation; } void setScale(float scale) { _scale = scale; } void setHeadRotation(glm::quat headRotation) { _headRotation = headRotation; } void setLeanSideways(float leanSideways) { _leanSideways = leanSideways; } void setLeanForward(float leanForward) { _leanForward = leanForward; } - void setLookAtPosition(glm::vec3& lookAtPosition) { _lookAtPosition = lookAtPosition; } + void setLookAtPosition(const glm::vec3& lookAtPosition) { _lookAtPosition = lookAtPosition; } private: QVector _blendshapeCoefficients; @@ -115,9 +115,9 @@ private: glm::vec3 _lookAtPosition; friend class Recorder; - friend void writeRecordingToFile(RecordingPointer recording, QString& file); - friend RecordingPointer readRecordingFromFile(RecordingPointer recording, QString& file); - friend RecordingPointer readRecordingFromRecFile(RecordingPointer recording, QString& filename, QByteArray& byteArray); + friend void writeRecordingToFile(RecordingPointer recording, const QString& file); + friend RecordingPointer readRecordingFromFile(RecordingPointer recording, const QString& file); + friend RecordingPointer readRecordingFromRecFile(RecordingPointer recording, const QString& filename, const QByteArray& byteArray); }; void writeRecordingToFile(RecordingPointer recording, QString& filename); From 2ee367fa44c43b1bf81568373c7b9526c4c90700 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 18 Sep 2014 11:14:17 -0700 Subject: [PATCH 09/23] add a couple of missing consts --- libraries/avatars/src/Player.cpp | 2 +- libraries/avatars/src/Recorder.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/avatars/src/Player.cpp b/libraries/avatars/src/Player.cpp index 3b74ce595a..402c108d57 100644 --- a/libraries/avatars/src/Player.cpp +++ b/libraries/avatars/src/Player.cpp @@ -159,7 +159,7 @@ void Player::loopRecording() { _timer.restart(); } -void Player::loadFromFile(QString& file) { +void Player::loadFromFile(const QString& file) { if (_recording) { _recording->clear(); } else { diff --git a/libraries/avatars/src/Recorder.cpp b/libraries/avatars/src/Recorder.cpp index ec21e2969c..b54c92744a 100644 --- a/libraries/avatars/src/Recorder.cpp +++ b/libraries/avatars/src/Recorder.cpp @@ -86,7 +86,7 @@ void Recorder::stopRecording() { qDebug().nospace() << "Recorded " << _recording->getFrameNumber() << " during " << _recording->getLength() << " msec (" << _recording->getFrameNumber() / (_recording->getLength() / 1000.0f) << " fps)"; } -void Recorder::saveToFile(QString& file) { +void Recorder::saveToFile(const QString& file) { if (_recording->isEmpty()) { qDebug() << "Cannot save recording to file, recording is empty."; } From 93d83b707d22534b0cd3301478f2c31879455c7e Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 18 Sep 2014 11:21:09 -0700 Subject: [PATCH 10/23] use a copy of filename in Recording.cpp to make changes to filename --- libraries/avatars/src/Recording.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/libraries/avatars/src/Recording.cpp b/libraries/avatars/src/Recording.cpp index 0bc323a8f7..f84b803c5f 100644 --- a/libraries/avatars/src/Recording.cpp +++ b/libraries/avatars/src/Recording.cpp @@ -781,17 +781,18 @@ RecordingPointer readRecordingFromRecFile(RecordingPointer recording, const QStr qDebug() << "Read " << byteArray.size() << " bytes in " << timer.elapsed() << " ms."; // Set new filename - if (filename.startsWith("http") || filename.startsWith("https") || filename.startsWith("ftp")) { - filename = QUrl(filename).fileName(); + QString newFilename = filename; + if (newFilename.startsWith("http") || newFilename.startsWith("https") || newFilename.startsWith("ftp")) { + newFilename = QUrl(newFilename).fileName(); } - if (filename.endsWith(".rec") || filename.endsWith(".REC")) { - filename.chop(qstrlen(".rec")); + if (newFilename.endsWith(".rec") || newFilename.endsWith(".REC")) { + newFilename.chop(qstrlen(".rec")); } - filename.append(".hfr"); - filename = QFileInfo(filename).absoluteFilePath(); + newFilename.append(".hfr"); + newFilename = QFileInfo(newFilename).absoluteFilePath(); // Set recording to new format - writeRecordingToFile(recording, filename); - qDebug() << "Recording has been successfully converted at" << filename; + writeRecordingToFile(recording, newFilename); + qDebug() << "Recording has been successfully converted at" << newFilename; return recording; } From b1abdc05a0b244f24133b26dab72ba0dc6f025b9 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 18 Sep 2014 11:25:50 -0700 Subject: [PATCH 11/23] add the last missing consts in Recording.h --- libraries/avatars/src/Recording.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/avatars/src/Recording.h b/libraries/avatars/src/Recording.h index bffa923ed0..99d40c6202 100644 --- a/libraries/avatars/src/Recording.h +++ b/libraries/avatars/src/Recording.h @@ -120,8 +120,8 @@ private: friend RecordingPointer readRecordingFromRecFile(RecordingPointer recording, const QString& filename, const QByteArray& byteArray); }; -void writeRecordingToFile(RecordingPointer recording, QString& filename); -RecordingPointer readRecordingFromFile(RecordingPointer recording, QString& filename); -RecordingPointer readRecordingFromRecFile(RecordingPointer recording, QString& filename, QByteArray& byteArray); +void writeRecordingToFile(RecordingPointer recording, const QString& filename); +RecordingPointer readRecordingFromFile(RecordingPointer recording, const QString& filename); +RecordingPointer readRecordingFromRecFile(RecordingPointer recording, const QString& filename, QByteArray& byteArray); #endif // hifi_Recording_h \ No newline at end of file From 1a5149af02119bcb34c288100e1eccd3514d7e57 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 18 Sep 2014 11:29:51 -0700 Subject: [PATCH 12/23] add another missing const to readRecordingFromRecFile --- libraries/avatars/src/Recording.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libraries/avatars/src/Recording.h b/libraries/avatars/src/Recording.h index 99d40c6202..aa14dc5d76 100644 --- a/libraries/avatars/src/Recording.h +++ b/libraries/avatars/src/Recording.h @@ -76,7 +76,8 @@ private: friend class Player; friend void writeRecordingToFile(RecordingPointer recording, const QString& file); friend RecordingPointer readRecordingFromFile(RecordingPointer recording, const QString& file); - friend RecordingPointer readRecordingFromRecFile(RecordingPointer recording, const QString& filename, const QByteArray& byteArray); + friend RecordingPointer readRecordingFromRecFile(RecordingPointer recording, const QString& filename, + const QByteArray& byteArray); }; /// Stores the different values associated to one recording frame @@ -117,11 +118,12 @@ private: friend class Recorder; friend void writeRecordingToFile(RecordingPointer recording, const QString& file); friend RecordingPointer readRecordingFromFile(RecordingPointer recording, const QString& file); - friend RecordingPointer readRecordingFromRecFile(RecordingPointer recording, const QString& filename, const QByteArray& byteArray); + friend RecordingPointer readRecordingFromRecFile(RecordingPointer recording, const QString& filename, + const QByteArray& byteArray); }; void writeRecordingToFile(RecordingPointer recording, const QString& filename); RecordingPointer readRecordingFromFile(RecordingPointer recording, const QString& filename); -RecordingPointer readRecordingFromRecFile(RecordingPointer recording, const QString& filename, QByteArray& byteArray); +RecordingPointer readRecordingFromRecFile(RecordingPointer recording, const QString& filename, const QByteArray& byteArray); #endif // hifi_Recording_h \ No newline at end of file From 37eb40122ca6fbce5b2746d1b8511417a0c5936b Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 18 Sep 2014 13:05:57 -0700 Subject: [PATCH 13/23] Tiny tweak to weight loading: only replace lowest weight if the new weight is greater. --- libraries/fbx/src/FBXReader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index 3c65540e57..3b9a340ed2 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -1769,7 +1769,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) lowestWeight = weights[k]; } } - if (k == 4) { + if (k == 4 && weight > lowestWeight) { // no space for an additional weight; we must replace the lowest weights[lowestIndex] = weight; extracted.mesh.clusterIndices[it.value()][lowestIndex] = i; From 256bd627fa9dedcbbf548ec67ef8d9f28b4f57f4 Mon Sep 17 00:00:00 2001 From: Craig Hansen-Sturm Date: Thu, 18 Sep 2014 13:12:53 -0700 Subject: [PATCH 14/23] clamp to 0.0f when within EPSILON neighborhood of 0.0f --- libraries/audio/src/AudioFilter.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/audio/src/AudioFilter.h b/libraries/audio/src/AudioFilter.h index c9458f280e..c792b5fec4 100644 --- a/libraries/audio/src/AudioFilter.h +++ b/libraries/audio/src/AudioFilter.h @@ -75,6 +75,8 @@ public: - (_b1 * _ym1) - (_b2 * _ym2); + y = (y >= -EPSILON && y < EPSILON) ? 0.0f : y; // clamp to 0 + // update delay line _xm2 = _xm1; _xm1 = x; From 9f3d908d9f87972e53b750a32f5876a591047fc7 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 18 Sep 2014 13:32:01 -0700 Subject: [PATCH 15/23] fix typo in comment --- interface/src/ui/DataWebDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/ui/DataWebDialog.cpp b/interface/src/ui/DataWebDialog.cpp index 9a67da48a8..0f70537b26 100644 --- a/interface/src/ui/DataWebDialog.cpp +++ b/interface/src/ui/DataWebDialog.cpp @@ -26,7 +26,7 @@ DataWebDialog::DataWebDialog() { // use an OAuthNetworkAccessManager instead of regular QNetworkAccessManager so our requests are authed page()->setNetworkAccessManager(OAuthNetworkAccessManager::getInstance()); - // have the page delete external links so they can be captured by the Application in case they are a hifi link + // have the page delegate external links so they can be captured by the Application in case they are a hifi link page()->setLinkDelegationPolicy(QWebPage::DelegateExternalLinks); // have the Application handle external links From 2383379a356386ff33b3fec7363b2ee15663552e Mon Sep 17 00:00:00 2001 From: Craig Hansen-Sturm Date: Thu, 18 Sep 2014 13:52:53 -0700 Subject: [PATCH 16/23] default sine gain set to -6db --- libraries/audio/src/AudioSourceTone.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/audio/src/AudioSourceTone.cpp b/libraries/audio/src/AudioSourceTone.cpp index da6eea6a9e..d1cd14be96 100644 --- a/libraries/audio/src/AudioSourceTone.cpp +++ b/libraries/audio/src/AudioSourceTone.cpp @@ -40,8 +40,8 @@ void AudioSourceTone::updateCoefficients() { void AudioSourceTone::initialize() { const float32_t FREQUENCY_220_HZ = 220.0f; - const float32_t GAIN_MINUS_3DB = 0.708f; - setParameters(SAMPLE_RATE, FREQUENCY_220_HZ, GAIN_MINUS_3DB); + const float32_t GAIN_MINUS_6DB = 0.501f; + setParameters(SAMPLE_RATE, FREQUENCY_220_HZ, GAIN_MINUS_6DB); } void AudioSourceTone::setParameters(const float32_t sampleRate, const float32_t frequency, const float32_t amplitude) { From 29ff8c09d9c2f81d8ad60d2c936144f1ff6acf90 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 18 Sep 2014 15:23:58 -0700 Subject: [PATCH 17/23] Fix LookAtPosition --- libraries/avatars/src/Player.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/avatars/src/Player.cpp b/libraries/avatars/src/Player.cpp index 402c108d57..b548d452e7 100644 --- a/libraries/avatars/src/Player.cpp +++ b/libraries/avatars/src/Player.cpp @@ -203,7 +203,7 @@ void Player::play() { head->setFinalPitch(eulers.x); head->setFinalYaw(eulers.y); head->setFinalRoll(eulers.z); - head->setLookAtPosition(currentFrame.getLookAtPosition()); + head->setLookAtPosition(context->position + context->orientation * currentFrame.getLookAtPosition()); } else { qDebug() << "WARNING: Player couldn't find head data."; } From 8e6d5da8fd7ea48fbfcc453f14bf3f1ac11df2cf Mon Sep 17 00:00:00 2001 From: Craig Hansen-Sturm Date: Thu, 18 Sep 2014 16:05:15 -0700 Subject: [PATCH 18/23] disable positional filter by default --- domain-server/resources/web/settings/describe.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domain-server/resources/web/settings/describe.json b/domain-server/resources/web/settings/describe.json index 2ea0aec0c7..fee7ff21fc 100644 --- a/domain-server/resources/web/settings/describe.json +++ b/domain-server/resources/web/settings/describe.json @@ -67,7 +67,7 @@ "type": "checkbox", "label": "Enable Positional Filter", "help": "If enabled, positional audio stream uses lowpass filter", - "default": true + "default": false } } } From b58c5f75dd92ce5ec46ed27f2cca68a13762ec66 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 18 Sep 2014 16:24:23 -0700 Subject: [PATCH 19/23] Fixes 0 makes a voxel when tool off --- examples/editVoxels.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/editVoxels.js b/examples/editVoxels.js index a85c04dd02..f4e468fd40 100644 --- a/examples/editVoxels.js +++ b/examples/editVoxels.js @@ -1110,7 +1110,7 @@ function keyPressEvent(event) { print("Color = " + (whichColor + 1)); swatchesSound.play(whichColor); moveTools(); - } else if (event.text == "0") { + } else if (event.text == "0" && voxelToolSelected) { // Create a brand new 1 meter voxel in front of your avatar var newPosition = getNewVoxelPosition(); var newVoxel = { From 58b1db4f0921f2ed92a957fd5604fe8f8bb0619b Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 18 Sep 2014 16:49:13 -0700 Subject: [PATCH 20/23] Added JS hooks for new Player options --- examples/Recorder.js | 13 ++++++++++--- libraries/avatars/src/AvatarData.cpp | 24 ++++++++++++++++++++++++ libraries/avatars/src/AvatarData.h | 4 ++++ 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/examples/Recorder.js b/examples/Recorder.js index 657e2d5206..8efa9408a9 100644 --- a/examples/Recorder.js +++ b/examples/Recorder.js @@ -12,7 +12,14 @@ Script.include("toolBars.js"); var recordingFile = "recording.rec"; -var playFromCurrentLocation = true; + +function setPlayerOptions() { + MyAvatar.setPlayFromCurrentLocation(true); + MyAvatar.setPlayerUseDisplayName(false); + MyAvatar.setPlayerUseAttachments(false); + MyAvatar.setPlayerUseHeadModel(false); + MyAvatar.setPlayerUseSkeletonModel(false); +} var windowDimensions = Controller.getViewportDimensions(); var TOOL_ICON_URL = "http://s3-us-west-1.amazonaws.com/highfidelity-public/images/tools/"; @@ -186,7 +193,7 @@ function mousePressEvent(event) { toolBar.setAlpha(ALPHA_ON, saveIcon); toolBar.setAlpha(ALPHA_ON, loadIcon); } else if (MyAvatar.playerLength() > 0) { - MyAvatar.setPlayFromCurrentLocation(playFromCurrentLocation); + setPlayerOptions(); MyAvatar.setPlayerLoop(false); MyAvatar.startPlaying(); toolBar.setAlpha(ALPHA_OFF, recordIcon); @@ -201,7 +208,7 @@ function mousePressEvent(event) { toolBar.setAlpha(ALPHA_ON, saveIcon); toolBar.setAlpha(ALPHA_ON, loadIcon); } else if (MyAvatar.playerLength() > 0) { - MyAvatar.setPlayFromCurrentLocation(playFromCurrentLocation); + setPlayerOptions(); MyAvatar.setPlayerLoop(true); MyAvatar.startPlaying(); toolBar.setAlpha(ALPHA_OFF, recordIcon); diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 200a6af6c7..5ac0c69864 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -661,6 +661,30 @@ void AvatarData::setPlayerLoop(bool loop) { } } +void AvatarData::setPlayerUseDisplayName(bool useDisplayName) { + if(_player) { + _player->useDisplayName(useDisplayName); + } +} + +void AvatarData::setPlayerUseAttachments(bool useAttachments) { + if(_player) { + _player->useAttachements(useAttachments); + } +} + +void AvatarData::setPlayerUseHeadModel(bool useHeadModel) { + if(_player) { + _player->useHeadModel(useHeadModel); + } +} + +void AvatarData::setPlayerUseSkeletonModel(bool useSkeletonModel) { + if(_player) { + _player->useSkeletonModel(useSkeletonModel); + } +} + void AvatarData::play() { if (isPlaying()) { if (QThread::currentThread() != thread()) { diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 3c373a0eda..bc68103ca6 100755 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -302,6 +302,10 @@ public slots: void startPlaying(); void setPlayFromCurrentLocation(bool playFromCurrentLocation); void setPlayerLoop(bool loop); + void setPlayerUseDisplayName(bool useDisplayName); + void setPlayerUseAttachments(bool useAttachments); + void setPlayerUseHeadModel(bool useHeadModel); + void setPlayerUseSkeletonModel(bool useSkeletonModel); void play(); void stopPlaying(); From 3ba178022eb84ec7841eaea3ec6fb4aa0aab447d Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 18 Sep 2014 17:02:11 -0700 Subject: [PATCH 21/23] Added new options to ControlledAC.js --- examples/ControlledAC.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/examples/ControlledAC.js b/examples/ControlledAC.js index 84a6c36082..33fa629ff8 100644 --- a/examples/ControlledAC.js +++ b/examples/ControlledAC.js @@ -12,6 +12,10 @@ // Set the following variables to the values needed var filename = "http://s3-us-west-1.amazonaws.com/highfidelity-public/ozan/bartender.rec"; var playFromCurrentLocation = true; +var useDisplayName = true; +var useAttachments = true; +var useHeadModel = true; +var useSkeletonModel = true; // ID of the agent. Two agents can't have the same ID. var id = 0; @@ -44,11 +48,15 @@ COLORS[SHOW] = { red: SHOW, green: 0, blue: 0 }; COLORS[HIDE] = { red: HIDE, green: 0, blue: 0 }; controlVoxelPosition.x += id * controlVoxelSize; - -Avatar.setPlayFromCurrentLocation(playFromCurrentLocation); Avatar.loadRecording(filename); +Avatar.setPlayFromCurrentLocation(playFromCurrentLocation); +Avatar.setPlayerUseDisplayName(useDisplayName); +Avatar.setPlayerUseAttachments(useAttachments); +Avatar.setPlayerUseHeadModel(useHeadModel); +Avatar.setPlayerUseSkeletonModel(useSkeletonModel); + function setupVoxelViewer() { var voxelViewerOffset = 10; var voxelViewerPosition = JSON.parse(JSON.stringify(controlVoxelPosition)); From c6d6c347cd94f9fa38bb46c4c029bb40c2950167 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Fri, 19 Sep 2014 08:48:55 -0700 Subject: [PATCH 22/23] head move using neck measurement for movement rather than head. --- examples/headMove.js | 57 +++++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 25 deletions(-) diff --git a/examples/headMove.js b/examples/headMove.js index 68a9a7833d..834c63c3ab 100644 --- a/examples/headMove.js +++ b/examples/headMove.js @@ -16,24 +16,21 @@ var debug = false; var movingWithHead = false; var headStartPosition, headStartDeltaPitch, headStartFinalPitch, headStartRoll, headStartYaw; -var HEAD_MOVE_DEAD_ZONE = 0.10; -var HEAD_STRAFE_DEAD_ZONE = 0.0; -var HEAD_ROTATE_DEAD_ZONE = 0.0; -//var HEAD_THRUST_FWD_SCALE = 12000.0; -//var HEAD_THRUST_STRAFE_SCALE = 0.0; -var HEAD_YAW_RATE = 1.0; +var HEAD_MOVE_DEAD_ZONE = 0.03; +var HEAD_STRAFE_DEAD_ZONE = 0.03; +var HEAD_ROTATE_DEAD_ZONE = 10.0; +var HEAD_YAW_RATE = 2.0; var HEAD_PITCH_RATE = 1.0; -//var HEAD_ROLL_THRUST_SCALE = 75.0; -//var HEAD_PITCH_LIFT_THRUST = 3.0; var WALL_BOUNCE = 4000.0; +var FIXED_WALK_VELOCITY = 1.5; // Modify these values to tweak the strength of the motion. // A larger *FACTOR increases the speed. // A lower SHORT_TIMESCALE makes the motor achieve full speed faster. var HEAD_VELOCITY_FWD_FACTOR = 20.0; -var HEAD_VELOCITY_LEFT_FACTOR = 20.0; +var HEAD_VELOCITY_LEFT_FACTOR = 0.0; var HEAD_VELOCITY_UP_FACTOR = 20.0; -var SHORT_TIMESCALE = 0.125; +var SHORT_TIMESCALE = 0.01; var VERY_LARGE_TIMESCALE = 1000000.0; var xAxis = {x:1.0, y:0.0, z:0.0 }; @@ -43,9 +40,10 @@ var zAxis = {x:0.0, y:0.0, z:1.0 }; // If these values are set to something var maxVelocity = 1.25; var noFly = true; +var fixedWalkVelocity = true; //var roomLimits = { xMin: 618, xMax: 635.5, zMin: 528, zMax: 552.5 }; -var roomLimits = { xMin: 142.6, xMax: 153.7, zMin: 177.5, zMax: 192.0 }; +var roomLimits = { xMin: 193.0, xMax: 206.5, zMin: 251.4, zMax: 269.5 }; function isInRoom(position) { var BUFFER = 2.0; @@ -74,32 +72,43 @@ function moveWithHead(deltaTime) { var position = MyAvatar.position; var neckPosition = MyAvatar.getNeckPosition(); var bodyLocalCurrentHeadVector = Vec3.subtract(neckPosition, position); - //bodyLocalCurrentHeadVector = Vec3.multiplyQbyV(Quat.inverse(MyAvatar.orientation), bodyLocalCurrentHeadVector); + bodyLocalCurrentHeadVector = Vec3.multiplyQbyV(Quat.inverse(MyAvatar.orientation), bodyLocalCurrentHeadVector); var headDelta = Vec3.subtract(bodyLocalCurrentHeadVector, headStartPosition); - //headDelta = Vec3.multiplyQbyV(Quat.inverse(Camera.getOrientation()), headDelta); headDelta.y = 0.0; // Don't respond to any of the vertical component of head motion - if (Vec3.length(headDelta) > 0.005) { - Vec3.print("headDelta = ", headDelta); - Vec3.print("headStartPosition = ", headStartPosition); - Vec3.print("MyAvatar.position = ", position); - Vec3.print("MyAvatar.getNeckPosition() = ", neckPosition); + headDelta = Vec3.multiplyQbyV(MyAvatar.orientation, headDelta); + headDelta = Vec3.multiplyQbyV(Quat.inverse(Camera.getOrientation()), headDelta); + + var length = Vec3.length(headDelta); + if (length > 1.0) { + // Needs fixed! Right now sometimes reported neck position jumps to a bad value + headDelta.x = headDelta.y = headDelta.z = 0.0; + length = 0.0; } - // Thrust based on leaning forward and side-to-side var targetVelocity = {x:0.0, y:0.0, z:0.0}; + if (length > HEAD_MOVE_DEAD_ZONE) { + targetVelocity = Vec3.multiply(headDelta, HEAD_VELOCITY_FWD_FACTOR); + } + /* if (Math.abs(headDelta.z) > HEAD_MOVE_DEAD_ZONE) { - targetVelocity = Vec3.multiply(zAxis, headDelta.z * HEAD_VELOCITY_FWD_FACTOR); + if (fixedWalkVelocity) { + targetVelocity = Vec3.multiply(zAxis, headDelta.z > 0 ? FIXED_WALK_VELOCITY : -FIXED_WALK_VELOCITY); + } else { + targetVelocity = Vec3.multiply(zAxis, headDelta.z * HEAD_VELOCITY_FWD_FACTOR); + } } if (Math.abs(headDelta.x) > HEAD_STRAFE_DEAD_ZONE) { var deltaVelocity = Vec3.multiply(xAxis, headDelta.x * HEAD_VELOCITY_LEFT_FACTOR); targetVelocity = Vec3.sum(targetVelocity, deltaVelocity); } + */ if (Math.abs(deltaYaw) > HEAD_ROTATE_DEAD_ZONE) { var orientation = Quat.multiply(Quat.angleAxis((deltaYaw + deltaRoll) * HEAD_YAW_RATE * deltaTime, yAxis), MyAvatar.orientation); MyAvatar.orientation = orientation; } + // Thrust Up/Down based on head pitch if (!noFly) { var deltaVelocity = Vec3.multiply(yAxis, headDelta.y * HEAD_VELOCITY_UP_FACTOR); @@ -140,10 +149,8 @@ function moveWithHead(deltaTime) { Controller.keyPressEvent.connect(function(event) { if (event.text == "SPACE" && !movingWithHead) { movingWithHead = true; - Vec3.print("getNeckPosition() = ", MyAvatar.getNeckPosition()); - headStartPosition = Vec3.subtract(MyAvatar.getNeckPosition(), MyAvatar.position); - //headStartPosition = Vec3.multiplyQbyV(Quat.inverse(MyAvatar.orientation), headStartPosition); - Vec3.print("First HeadStartPosition = ", headStartPosition); + headStartPosition = Vec3.subtract(MyAvatar.getNeckPosition(), MyAvatar.position); + headStartPosition = Vec3.multiplyQbyV(Quat.inverse(MyAvatar.orientation), headStartPosition); headStartDeltaPitch = MyAvatar.getHeadDeltaPitch(); headStartFinalPitch = MyAvatar.getHeadFinalPitch(); headStartRoll = MyAvatar.getHeadFinalRoll(); @@ -151,7 +158,7 @@ Controller.keyPressEvent.connect(function(event) { // start with disabled motor -- it will be updated shortly MyAvatar.motorTimescale = VERY_LARGE_TIMESCALE; MyAvatar.motorVelocity = {x:0.0, y:0.0, z:0.0}; - MyAvatar.motorReferenceFrame = "avatar"; // alternatives are: "avatar" and "world" + MyAvatar.motorReferenceFrame = "camera"; // alternatives are: "avatar" and "world" } }); From 6c808f2979cd324c0c563af225549365dbfcfe2c Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Fri, 19 Sep 2014 09:22:27 -0700 Subject: [PATCH 23/23] final tweaks to movement script --- examples/headMove.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/examples/headMove.js b/examples/headMove.js index 834c63c3ab..4d432c28b3 100644 --- a/examples/headMove.js +++ b/examples/headMove.js @@ -16,18 +16,18 @@ var debug = false; var movingWithHead = false; var headStartPosition, headStartDeltaPitch, headStartFinalPitch, headStartRoll, headStartYaw; -var HEAD_MOVE_DEAD_ZONE = 0.03; +var HEAD_MOVE_DEAD_ZONE = 0.05; var HEAD_STRAFE_DEAD_ZONE = 0.03; var HEAD_ROTATE_DEAD_ZONE = 10.0; -var HEAD_YAW_RATE = 2.0; +var HEAD_YAW_RATE = 1.5; var HEAD_PITCH_RATE = 1.0; -var WALL_BOUNCE = 4000.0; +var WALL_BOUNCE = 10000.0; var FIXED_WALK_VELOCITY = 1.5; // Modify these values to tweak the strength of the motion. // A larger *FACTOR increases the speed. // A lower SHORT_TIMESCALE makes the motor achieve full speed faster. -var HEAD_VELOCITY_FWD_FACTOR = 20.0; +var HEAD_VELOCITY_FWD_FACTOR = 10.0; var HEAD_VELOCITY_LEFT_FACTOR = 0.0; var HEAD_VELOCITY_UP_FACTOR = 20.0; var SHORT_TIMESCALE = 0.01; @@ -84,11 +84,14 @@ function moveWithHead(deltaTime) { // Needs fixed! Right now sometimes reported neck position jumps to a bad value headDelta.x = headDelta.y = headDelta.z = 0.0; length = 0.0; + return; } // Thrust based on leaning forward and side-to-side var targetVelocity = {x:0.0, y:0.0, z:0.0}; if (length > HEAD_MOVE_DEAD_ZONE) { + //headDelta = Vec3.normalize(headDelta); + //targetVelocity = Vec3.multiply(headDelta, FIXED_WALK_VELOCITY); targetVelocity = Vec3.multiply(headDelta, HEAD_VELOCITY_FWD_FACTOR); } /* @@ -140,7 +143,7 @@ function moveWithHead(deltaTime) { if (movingWithHead && Vec3.length(thrust) > 0.0) { // reduce the timescale of the motor so that it won't defeat the thrust code Vec3.print("adebug room containment thrust = ", thrust); - motorTimescale = 4.0 * SHORT_TIMESCALE; + motorTimescale = 1000000.0; } } MyAvatar.motorTimescale = motorTimescale;