From 3ca20a7eeef7f44bbb8698e84970fc72f7519a89 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Tue, 2 Dec 2014 23:08:34 -0800 Subject: [PATCH 1/6] Add jump/warp turning when in HMD --- interface/src/avatar/MyAvatar.cpp | 24 ++++++++++++++++++++++-- interface/src/avatar/MyAvatar.h | 1 + 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 3301cf0347..a07a3d9b28 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -68,6 +68,7 @@ const int SCRIPTED_MOTOR_WORLD_FRAME = 2; MyAvatar::MyAvatar() : Avatar(), _mousePressed(false), + _turningKeyPressTime(0.0f), _bodyPitchDelta(0.0f), _bodyRollDelta(0.0f), _gravity(0.0f, 0.0f, 0.0f), @@ -1169,8 +1170,27 @@ bool MyAvatar::shouldRenderHead(const glm::vec3& cameraPosition, RenderMode rend void MyAvatar::updateOrientation(float deltaTime) { // Gather rotation information from keyboard - _bodyYawDelta -= _driveKeys[ROT_RIGHT] * YAW_SPEED * deltaTime; - _bodyYawDelta += _driveKeys[ROT_LEFT] * YAW_SPEED * deltaTime; + const float TIME_BETWEEN_HMD_TURNS = 0.5f; + const float HMD_TURN_DEGREES = 22.5f; + if (!OculusManager::isConnected()) { + // Smoothly rotate body with arrow keys if not in HMD + _bodyYawDelta -= _driveKeys[ROT_RIGHT] * YAW_SPEED * deltaTime; + _bodyYawDelta += _driveKeys[ROT_LEFT] * YAW_SPEED * deltaTime; + } else { + // Jump turns if in HMD + if (_driveKeys[ROT_RIGHT] || _driveKeys[ROT_LEFT]) { + if (_turningKeyPressTime == 0.0f) { + setOrientation(getOrientation() * + glm::quat(glm::radians(glm::vec3(0.f, _driveKeys[ROT_LEFT] ? HMD_TURN_DEGREES : -HMD_TURN_DEGREES, 0.0f)))); + } + _turningKeyPressTime += deltaTime; + if (_turningKeyPressTime > TIME_BETWEEN_HMD_TURNS) { + _turningKeyPressTime = 0.0f; + } + } else { + _turningKeyPressTime = 0.0f; + } + } getHead()->setBasePitch(getHead()->getBasePitch() + (_driveKeys[ROT_UP] - _driveKeys[ROT_DOWN]) * PITCH_SPEED * deltaTime); // update body yaw by body yaw delta diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index dd1178c7b5..6926ac9505 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -204,6 +204,7 @@ protected: private: bool _mousePressed; + float _turningKeyPressTime; float _bodyPitchDelta; // degrees float _bodyRollDelta; // degrees glm::vec3 _gravity; From 57e2f71bb7fd7701e299acbb1038c1da1942aa19 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Tue, 2 Dec 2014 23:24:47 -0800 Subject: [PATCH 2/6] remove unused body delta pitch, roll --- interface/src/avatar/MyAvatar.cpp | 14 +++----------- interface/src/avatar/MyAvatar.h | 2 -- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index a07a3d9b28..a4fc696bc9 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -69,8 +69,6 @@ MyAvatar::MyAvatar() : Avatar(), _mousePressed(false), _turningKeyPressTime(0.0f), - _bodyPitchDelta(0.0f), - _bodyRollDelta(0.0f), _gravity(0.0f, 0.0f, 0.0f), _distanceToNearestAvatar(std::numeric_limits::max()), _shouldJump(false), @@ -1193,22 +1191,18 @@ void MyAvatar::updateOrientation(float deltaTime) { } getHead()->setBasePitch(getHead()->getBasePitch() + (_driveKeys[ROT_UP] - _driveKeys[ROT_DOWN]) * PITCH_SPEED * deltaTime); - // update body yaw by body yaw delta - glm::quat orientation = getOrientation() * glm::quat(glm::radians( - glm::vec3(_bodyPitchDelta, _bodyYawDelta, _bodyRollDelta) * deltaTime)); + // update body orientation by movement inputs + setOrientation(getOrientation() * + glm::quat(glm::radians(glm::vec3(0.0f, _bodyYawDelta, 0.0f) * deltaTime))); // decay body rotation momentum const float BODY_SPIN_FRICTION = 7.5f; float bodySpinMomentum = 1.0f - BODY_SPIN_FRICTION * deltaTime; if (bodySpinMomentum < 0.0f) { bodySpinMomentum = 0.0f; } - _bodyPitchDelta *= bodySpinMomentum; _bodyYawDelta *= bodySpinMomentum; - _bodyRollDelta *= bodySpinMomentum; float MINIMUM_ROTATION_RATE = 2.0f; if (fabs(_bodyYawDelta) < MINIMUM_ROTATION_RATE) { _bodyYawDelta = 0.0f; } - if (fabs(_bodyRollDelta) < MINIMUM_ROTATION_RATE) { _bodyRollDelta = 0.0f; } - if (fabs(_bodyPitchDelta) < MINIMUM_ROTATION_RATE) { _bodyPitchDelta = 0.0f; } if (OculusManager::isConnected()) { // these angles will be in radians @@ -1237,8 +1231,6 @@ void MyAvatar::updateOrientation(float deltaTime) { } - // update the euler angles - setOrientation(orientation); } glm::vec3 MyAvatar::applyKeyboardMotor(float deltaTime, const glm::vec3& localVelocity, bool hasFloor) { diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 6926ac9505..37b93e2f04 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -205,8 +205,6 @@ protected: private: bool _mousePressed; float _turningKeyPressTime; - float _bodyPitchDelta; // degrees - float _bodyRollDelta; // degrees glm::vec3 _gravity; float _distanceToNearestAvatar; // How close is the nearest avatar? From d63ace9f6108a8fcef1a752d65189ab59b2c7dfd Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Tue, 2 Dec 2014 23:53:46 -0800 Subject: [PATCH 3/6] fix angular velocity from oculus, tweak hair --- interface/src/Hair.cpp | 4 ++-- interface/src/avatar/MyAvatar.cpp | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/interface/src/Hair.cpp b/interface/src/Hair.cpp index e14fc519d3..cb664f39ed 100644 --- a/interface/src/Hair.cpp +++ b/interface/src/Hair.cpp @@ -18,8 +18,8 @@ const float HAIR_DAMPING = 0.99f; const float CONSTRAINT_RELAXATION = 10.0f; const float HAIR_ACCELERATION_COUPLING = 0.045f; -const float HAIR_ANGULAR_VELOCITY_COUPLING = 0.020f; -const float HAIR_ANGULAR_ACCELERATION_COUPLING = 0.003f; +const float HAIR_ANGULAR_VELOCITY_COUPLING = 0.001f; +const float HAIR_ANGULAR_ACCELERATION_COUPLING = 0.001f; const float HAIR_MAX_LINEAR_ACCELERATION = 4.0f; const float HAIR_STIFFNESS = 0.00f; const glm::vec3 HAIR_COLOR1(0.98f, 0.76f, 0.075f); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index a4fc696bc9..9f3309ece2 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1215,8 +1215,11 @@ void MyAvatar::updateOrientation(float deltaTime) { // Record the angular velocity Head* head = getHead(); - glm::vec3 angularVelocity(yaw - head->getBaseYaw(), pitch - head->getBasePitch(), roll - head->getBaseRoll()); - head->setAngularVelocity(angularVelocity); + if (deltaTime > 0.0f) { + glm::vec3 angularVelocity(pitch - head->getBasePitch(), yaw - head->getBaseYaw(), roll - head->getBaseRoll()); + angularVelocity *= 1.0f / deltaTime; + head->setAngularVelocity(angularVelocity); + } //Invert yaw and roll when in mirror mode if (Application::getInstance()->getCamera()->getMode() == CAMERA_MODE_MIRROR) { From 49a087018f0a8d48c14f5634f91fc8f62407ca17 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 3 Dec 2014 08:22:50 -0800 Subject: [PATCH 4/6] fix for delayed heartbeats, late socket lookup --- domain-server/src/DomainServer.cpp | 31 ++++++++++++++-------- domain-server/src/DomainServer.h | 2 ++ libraries/networking/src/HifiSockAddr.cpp | 2 ++ libraries/networking/src/HifiSockAddr.h | 3 +++ libraries/networking/src/LimitedNodeList.h | 1 + 5 files changed, 28 insertions(+), 11 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 80777ce529..75db0b8022 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -37,6 +37,8 @@ int const DomainServer::EXIT_CODE_REBOOT = 234923; +const QString ICE_SERVER_DEFAULT_HOSTNAME = "ice.highfidelity.io"; + DomainServer::DomainServer(int argc, char* argv[]) : QCoreApplication(argc, argv), _shutdownEventListener(this), @@ -52,7 +54,8 @@ DomainServer::DomainServer(int argc, char* argv[]) : _webAuthenticationStateSet(), _cookieSessionHash(), _automaticNetworkingSetting(), - _settingsManager() + _settingsManager(), + _iceServerSocket(ICE_SERVER_DEFAULT_HOSTNAME, ICE_SERVER_DEFAULT_PORT) { LogUtils::init(); @@ -346,6 +349,9 @@ void DomainServer::setupAutomaticNetworking() { QTimer* dynamicIPTimer = new QTimer(this); connect(dynamicIPTimer, &QTimer::timeout, this, &DomainServer::requestCurrentPublicSocketViaSTUN); + _automaticNetworkingSetting = + _settingsManager.valueOrDefaultValueForKeyPath(METAVERSE_AUTOMATIC_NETWORKING_KEY_PATH).toString(); + if (_automaticNetworkingSetting == FULL_AUTOMATIC_NETWORKING_VALUE) { dynamicIPTimer->start(STUN_REFLEXIVE_KEEPALIVE_INTERVAL_MSECS); @@ -354,9 +360,17 @@ void DomainServer::setupAutomaticNetworking() { connect(iceHeartbeatTimer, &QTimer::timeout, this, &DomainServer::performICEUpdates); iceHeartbeatTimer->start(ICE_HEARBEAT_INTERVAL_MSECS); - // call our sendHeartbeaToIceServer immediately anytime a local or public socket changes + // call our sendHeartbeatToIceServer immediately anytime a local or public socket changes connect(nodeList, &LimitedNodeList::localSockAddrChanged, this, &DomainServer::sendHeartbeatToIceServer); connect(nodeList, &LimitedNodeList::publicSockAddrChanged, this, &DomainServer::sendHeartbeatToIceServer); + + // attempt to update our public socket now, this will send a heartbeat once we get public socket + requestCurrentPublicSocketViaSTUN(); + + // in case the STUN lookup is still happening we should re-request a public socket once we get that address + connect(&nodeList->getSTUNSockAddr(), &HifiSockAddr::lookupCompleted, + this, &DomainServer::requestCurrentPublicSocketViaSTUN); + } if (!didSetupAccountManagerWithAccessToken()) { @@ -366,9 +380,6 @@ void DomainServer::setupAutomaticNetworking() { return; } - _automaticNetworkingSetting = - _settingsManager.valueOrDefaultValueForKeyPath(METAVERSE_AUTOMATIC_NETWORKING_KEY_PATH).toString(); - if (_automaticNetworkingSetting == IP_ONLY_AUTOMATIC_NETWORKING_VALUE || _automaticNetworkingSetting == FULL_AUTOMATIC_NETWORKING_VALUE) { @@ -383,14 +394,13 @@ void DomainServer::setupAutomaticNetworking() { // send public socket changes to the data server so nodes can find us at our new IP connect(nodeList, &LimitedNodeList::publicSockAddrChanged, this, &DomainServer::performIPAddressUpdate); + + // attempt to update our sockets now + requestCurrentPublicSocketViaSTUN(); } else { // send our heartbeat to data server so it knows what our network settings are sendHeartbeatToDataServer(); } - - // attempt to update our sockets now - requestCurrentPublicSocketViaSTUN(); - } else { qDebug() << "Cannot enable domain-server automatic networking without a domain ID." << "Please add an ID to your config file or via the web interface."; @@ -1167,8 +1177,7 @@ void DomainServer::performICEUpdates() { } void DomainServer::sendHeartbeatToIceServer() { - static HifiSockAddr ICE_SERVER_SOCK_ADDR = HifiSockAddr("ice.highfidelity.io", ICE_SERVER_DEFAULT_PORT); - LimitedNodeList::getInstance()->sendHeartbeatToIceServer(ICE_SERVER_SOCK_ADDR); + LimitedNodeList::getInstance()->sendHeartbeatToIceServer(_iceServerSocket); } void DomainServer::sendICEPingPackets() { diff --git a/domain-server/src/DomainServer.h b/domain-server/src/DomainServer.h index de485da5e7..2a92c63923 100644 --- a/domain-server/src/DomainServer.h +++ b/domain-server/src/DomainServer.h @@ -154,6 +154,8 @@ private: QString _automaticNetworkingSetting; DomainServerSettingsManager _settingsManager; + + HifiSockAddr _iceServerSocket; }; diff --git a/libraries/networking/src/HifiSockAddr.cpp b/libraries/networking/src/HifiSockAddr.cpp index f2419f5124..425dffefe9 100644 --- a/libraries/networking/src/HifiSockAddr.cpp +++ b/libraries/networking/src/HifiSockAddr.cpp @@ -86,6 +86,7 @@ bool HifiSockAddr::operator==(const HifiSockAddr& rhsSockAddr) const { void HifiSockAddr::handleLookupResult(const QHostInfo& hostInfo) { if (hostInfo.error() != QHostInfo::NoError) { qDebug() << "Lookup failed for" << hostInfo.lookupId() << ":" << hostInfo.errorString(); + emit lookupFailed(); } foreach(const QHostAddress& address, hostInfo.addresses()) { @@ -94,6 +95,7 @@ void HifiSockAddr::handleLookupResult(const QHostInfo& hostInfo) { _address = address; qDebug() << "QHostInfo lookup result for" << hostInfo.hostName() << "with lookup ID" << hostInfo.lookupId() << "is" << address.toString(); + emit lookupCompleted(); break; } } diff --git a/libraries/networking/src/HifiSockAddr.h b/libraries/networking/src/HifiSockAddr.h index 064f8032ca..4d3944012e 100644 --- a/libraries/networking/src/HifiSockAddr.h +++ b/libraries/networking/src/HifiSockAddr.h @@ -54,6 +54,9 @@ public: friend QDataStream& operator>>(QDataStream& dataStream, HifiSockAddr& sockAddr); private slots: void handleLookupResult(const QHostInfo& hostInfo); +signals: + void lookupCompleted(); + void lookupFailed(); private: QHostAddress _address; quint16 _port; diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index ad8c1688bb..2fc8751e3f 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -105,6 +105,7 @@ public: const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket); const HifiSockAddr& getLocalSockAddr() const { return _localSockAddr; } + const HifiSockAddr& getSTUNSockAddr() const { return _stunSockAddr; } void processNodeData(const HifiSockAddr& senderSockAddr, const QByteArray& packet); void processKillNode(const QByteArray& datagram); From 98f56aaa0c81955a6db55243a3b3d09b3e4a9aef Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 3 Dec 2014 09:55:55 -0800 Subject: [PATCH 5/6] fix URL/filename discrepancy for local scripts --- interface/src/Application.cpp | 10 ++++----- interface/src/Application.h | 4 ++-- libraries/script-engine/src/ScriptEngine.cpp | 23 ++++++++++---------- libraries/script-engine/src/ScriptEngine.h | 4 ++-- 4 files changed, 20 insertions(+), 21 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9561115478..9c3eb48993 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4042,20 +4042,20 @@ ScriptEngine* Application::loadScript(const QString& scriptFilename, bool isUser return scriptEngine; } -void Application::handleScriptEngineLoaded(const QUrl& scriptURL) { +void Application::handleScriptEngineLoaded(const QString& scriptFilename) { ScriptEngine* scriptEngine = qobject_cast(sender()); - _scriptEnginesHash.insertMulti(scriptURL.toString(), scriptEngine); + _scriptEnginesHash.insertMulti(scriptFilename, scriptEngine); _runningScriptsWidget->setRunningScripts(getRunningScripts()); - UserActivityLogger::getInstance().loadedScript(scriptURL.toString()); + UserActivityLogger::getInstance().loadedScript(scriptFilename); // register our application services and set it off on its own thread registerScriptEngineWithApplicationServices(scriptEngine); } -void Application::handleScriptLoadError(const QUrl& scriptURL) { +void Application::handleScriptLoadError(const QString& scriptFilename) { qDebug() << "Application::loadScript(), script failed to load..."; - QMessageBox::warning(getWindow(), "Error Loading Script", scriptURL.toString() + " failed to load."); + QMessageBox::warning(getWindow(), "Error Loading Script", scriptFilename + " failed to load."); } void Application::scriptFinished(const QString& scriptName) { diff --git a/interface/src/Application.h b/interface/src/Application.h index caaebea876..92ef00e8a5 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -394,8 +394,8 @@ private slots: void idle(); void aboutToQuit(); - void handleScriptEngineLoaded(const QUrl& scriptURL); - void handleScriptLoadError(const QUrl& scriptURL); + void handleScriptEngineLoaded(const QString& scriptFilename); + void handleScriptLoadError(const QString& scriptFilename); void connectedToDomain(const QString& hostname); diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 6cef69d23f..70c536e116 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -156,31 +156,30 @@ void ScriptEngine::loadURL(const QUrl& scriptURL) { if (_isRunning) { return; } - - QString scriptURLString = scriptURL.toString(); - _fileNameString = scriptURLString; + + _fileNameString = scriptURL.toString(); QUrl url(scriptURL); // if the scheme length is one or lower, maybe they typed in a file, let's try const int WINDOWS_DRIVE_LETTER_SIZE = 1; if (url.scheme().size() <= WINDOWS_DRIVE_LETTER_SIZE) { - url = QUrl::fromLocalFile(scriptURLString); + url = QUrl::fromLocalFile(_fileNameString); } // ok, let's see if it's valid... and if so, load it if (url.isValid()) { if (url.scheme() == "file") { - QString fileName = url.toLocalFile(); - QFile scriptFile(fileName); + _fileNameString = url.toLocalFile(); + QFile scriptFile(_fileNameString); if (scriptFile.open(QFile::ReadOnly | QFile::Text)) { - qDebug() << "Loading file:" << fileName; + qDebug() << "ScriptEngine loading file:" << _fileNameString; QTextStream in(&scriptFile); _scriptContents = in.readAll(); - emit scriptLoaded(url); + emit scriptLoaded(_fileNameString); } else { - qDebug() << "ERROR Loading file:" << fileName; - emit errorLoadingScript(url); + qDebug() << "ERROR Loading file:" << _fileNameString; + emit errorLoadingScript(_fileNameString); } } else { QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); @@ -195,10 +194,10 @@ void ScriptEngine::handleScriptDownload() { if (reply->error() == QNetworkReply::NoError && reply->attribute(QNetworkRequest::HttpStatusCodeAttribute) == 200) { _scriptContents = reply->readAll(); - emit scriptLoaded(reply->url()); + emit scriptLoaded(_fileNameString); } else { qDebug() << "ERROR Loading file:" << reply->url().toString(); - emit errorLoadingScript(reply->url()); + emit errorLoadingScript(_fileNameString); } } diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index 4b6b3e48ab..fd28e98cab 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -107,8 +107,8 @@ public slots: void nodeKilled(SharedNodePointer node); signals: - void scriptLoaded(const QUrl& scriptURL); - void errorLoadingScript(const QUrl& scriptURL); + void scriptLoaded(const QString& scriptFilename); + void errorLoadingScript(const QString& scriptFilename); void update(float deltaTime); void scriptEnding(); void finished(const QString& fileNameString); From f0b0c5fe0b546912581468f2c277df7aefed9fe6 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 3 Dec 2014 11:08:41 -0800 Subject: [PATCH 6/6] change warp button to button face right --- examples/gamepad.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/gamepad.js b/examples/gamepad.js index b4c2758edd..a2f1034e26 100644 --- a/examples/gamepad.js +++ b/examples/gamepad.js @@ -20,7 +20,7 @@ var BUTTON_TURN_AROUND = Joysticks.BUTTON_RIGHT_STICK; var BUTTON_FLY_UP = Joysticks.BUTTON_RIGHT_SHOULDER; var BUTTON_FLY_DOWN = Joysticks.BUTTON_LEFT_SHOULDER; -var BUTTON_WARP = Joysticks.BUTTON_FACE_BOTTOM; +var BUTTON_WARP = Joysticks.BUTTON_FACE_RIGHT; var BUTTON_WARP_FORWARD = Joysticks.BUTTON_DPAD_UP; var BUTTON_WARP_BACKWARD = Joysticks.BUTTON_DPAD_DOWN;