From 4cef21aa4f0983ba909e864e49e5de342d995ea5 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 16 Sep 2014 09:14:06 -0700 Subject: [PATCH 1/3] don't prepend relative paths with hifi scheme --- libraries/networking/src/AddressManager.cpp | 44 ++++++++++++--------- 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index 13af32bc83..b594ac6d37 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -61,25 +61,25 @@ bool AddressManager::handleUrl(const QUrl& lookupUrl) { // 3. location string (posX,posY,posZ/eulerX,eulerY,eulerZ) // 4. domain network address (IP or dns resolvable hostname) - if (lookupUrl.isRelative()) { - // if this is a relative path then handle it as a relative viewpoint - handleRelativeViewpoint(lookupUrl.path()); - } else { - // use our regex'ed helpers to figure out what we're supposed to do with this - if (!handleUsername(lookupUrl.authority())) { - // we're assuming this is either a network address or global place name - // check if it is a network address first - if (!handleNetworkAddress(lookupUrl.host())) { - // wasn't an address - lookup the place name - attemptPlaceNameLookup(lookupUrl.host()); - } - - // we may have a path that defines a relative viewpoint - if so we should jump to that now - handleRelativeViewpoint(lookupUrl.path()); + // use our regex'ed helpers to figure out what we're supposed to do with this + if (!handleUsername(lookupUrl.authority())) { + // we're assuming this is either a network address or global place name + // check if it is a network address first + if (!handleNetworkAddress(lookupUrl.host())) { + // wasn't an address - lookup the place name + attemptPlaceNameLookup(lookupUrl.host()); } + + // we may have a path that defines a relative viewpoint - if so we should jump to that now + handleRelativeViewpoint(lookupUrl.path()); } return true; + } else if (lookupUrl.toString().startsWith('/')) { + qDebug() << "Going to relative path" << lookupUrl.path(); + + // if this is a relative path then handle it as a relative viewpoint + handleRelativeViewpoint(lookupUrl.path()); } return false; @@ -89,10 +89,18 @@ void AddressManager::handleLookupString(const QString& lookupString) { if (!lookupString.isEmpty()) { // make this a valid hifi URL and handle it off to handleUrl QString sanitizedString = lookupString; - const QRegExp HIFI_SCHEME_REGEX = QRegExp(HIFI_URL_SCHEME + ":\\/{1,2}", Qt::CaseInsensitive); - sanitizedString = sanitizedString.remove(HIFI_SCHEME_REGEX); + QUrl lookupURL; - handleUrl(QUrl(HIFI_URL_SCHEME + "://" + sanitizedString)); + if (!lookupString.startsWith('/')) { + const QRegExp HIFI_SCHEME_REGEX = QRegExp(HIFI_URL_SCHEME + ":\\/{1,2}", Qt::CaseInsensitive); + sanitizedString = sanitizedString.remove(HIFI_SCHEME_REGEX); + + lookupURL = QUrl(HIFI_URL_SCHEME + "://" + sanitizedString); + } else { + lookupURL = QUrl(lookupString); + } + + handleUrl(lookupURL); } } From 0033dfe5af4bb0ff5fbca0e83572aa8d5ec7c6b4 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 16 Sep 2014 09:57:21 -0700 Subject: [PATCH 2/3] use quat orientation to store locations and user locations --- interface/src/avatar/MyAvatar.cpp | 24 ++++++++---- interface/src/avatar/MyAvatar.h | 4 +- libraries/networking/src/AddressManager.cpp | 43 +++++++++++++-------- libraries/networking/src/AddressManager.h | 4 +- libraries/shared/src/GLMHelpers.cpp | 5 +++ libraries/shared/src/GLMHelpers.h | 1 + 6 files changed, 54 insertions(+), 27 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 6cad3d4296..66a867ec0f 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1766,25 +1766,33 @@ void MyAvatar::resetSize() { qDebug("Reseted scale to %f", _targetScale); } -void MyAvatar::goToLocation(const glm::vec3& newPosition, bool hasOrientation, const glm::vec3& newOrientation) { - glm::quat quatOrientation = getOrientation(); +void MyAvatar::goToLocation(const glm::vec3& newPosition, + bool hasOrientation, const glm::quat& newOrientation, + bool shouldFaceLocation) { qDebug().nospace() << "MyAvatar goToLocation - moving to " << newPosition.x << ", " << newPosition.y << ", " << newPosition.z; + glm::vec3 shiftedPosition = newPosition; + if (hasOrientation) { qDebug().nospace() << "MyAvatar goToLocation - new orientation is " - << newOrientation.x << ", " << newOrientation.y << ", " << newOrientation.z; + << newOrientation.x << ", " << newOrientation.y << ", " << newOrientation.z << ", " << newOrientation.w; // orient the user to face the target - glm::quat quatOrientation = glm::quat(glm::radians(newOrientation)) - * glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f)); + glm::quat quatOrientation = newOrientation; + + if (shouldFaceLocation) { + quatOrientation = newOrientation * glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f)); + + // move the user a couple units away + const float DISTANCE_TO_USER = 2.0f; + shiftedPosition = newPosition - quatOrientation * IDENTITY_FRONT * DISTANCE_TO_USER; + } + setOrientation(quatOrientation); } - // move the user a couple units away - const float DISTANCE_TO_USER = 2.0f; - glm::vec3 shiftedPosition = newPosition - quatOrientation * IDENTITY_FRONT * DISTANCE_TO_USER; slamPosition(shiftedPosition); emit transformChanged(); } diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index d86829ea91..21b344c724 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -154,7 +154,9 @@ public slots: void decreaseSize(); void resetSize(); - void goToLocation(const glm::vec3& newPosition, bool hasOrientation = false, const glm::vec3& newOrientation = glm::vec3()); + void goToLocation(const glm::vec3& newPosition, + bool hasOrientation = false, const glm::quat& newOrientation = glm::quat(), + bool shouldFaceLocation = false); // Set/Get update the thrust that will move the avatar around void addThrust(glm::vec3 newThrust) { _thrust += newThrust; }; diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index b594ac6d37..400121a49b 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -28,7 +28,7 @@ QString AddressManager::pathForPositionAndOrientation(const glm::vec3& position, QString pathString = "/" + createByteArray(position); if (hasOrientation) { - QString orientationString = createByteArray(glm::degrees(safeEulerAngles(orientation))); + QString orientationString = createByteArray(orientation); pathString += "/" + orientationString; } @@ -193,36 +193,45 @@ bool AddressManager::handleNetworkAddress(const QString& lookupString) { bool AddressManager::handleRelativeViewpoint(const QString& lookupString) { const QString FLOAT_REGEX_STRING = "([-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?)"; - const QString TRIPLE_FLOAT_REGEX_STRING = QString("\\/") + FLOAT_REGEX_STRING + "\\s*,\\s*" + - FLOAT_REGEX_STRING + "\\s*,\\s*" + FLOAT_REGEX_STRING + "\\s*(?:$|\\/)"; + const QString SPACED_COMMA_REGEX_STRING = "\\s*,\\s*"; + const QString POSITION_REGEX_STRING = QString("\\/") + FLOAT_REGEX_STRING + SPACED_COMMA_REGEX_STRING + + FLOAT_REGEX_STRING + SPACED_COMMA_REGEX_STRING + FLOAT_REGEX_STRING + "\\s*(?:$|\\/)"; + const QString QUAT_REGEX_STRING = QString("\\/") + FLOAT_REGEX_STRING + SPACED_COMMA_REGEX_STRING + + FLOAT_REGEX_STRING + SPACED_COMMA_REGEX_STRING + FLOAT_REGEX_STRING + SPACED_COMMA_REGEX_STRING + + FLOAT_REGEX_STRING + "\\s*$"; - QRegExp tripleFloatRegex(TRIPLE_FLOAT_REGEX_STRING); + QRegExp positionRegex(POSITION_REGEX_STRING); - if (tripleFloatRegex.indexIn(lookupString) != -1) { + if (positionRegex.indexIn(lookupString) != -1) { // we have at least a position, so emit our signal to say we need to change position - glm::vec3 newPosition(tripleFloatRegex.cap(1).toFloat(), - tripleFloatRegex.cap(2).toFloat(), - tripleFloatRegex.cap(3).toFloat()); + glm::vec3 newPosition(positionRegex.cap(1).toFloat(), + positionRegex.cap(2).toFloat(), + positionRegex.cap(3).toFloat()); if (!isNaN(newPosition.x) && !isNaN(newPosition.y) && !isNaN(newPosition.z)) { - glm::vec3 newOrientation; + glm::quat newOrientation; + + QRegExp orientationRegex(QUAT_REGEX_STRING); + // we may also have an orientation - if (lookupString[tripleFloatRegex.matchedLength() - 1] == QChar('/') - && tripleFloatRegex.indexIn(lookupString, tripleFloatRegex.matchedLength() - 1) != -1) { + if (lookupString[positionRegex.matchedLength() - 1] == QChar('/') + && orientationRegex.indexIn(lookupString, positionRegex.matchedLength() - 1) != -1) { - glm::vec3 newOrientation(tripleFloatRegex.cap(1).toFloat(), - tripleFloatRegex.cap(2).toFloat(), - tripleFloatRegex.cap(3).toFloat()); + glm::quat newOrientation = glm::normalize(glm::quat(orientationRegex.cap(4).toFloat(), + orientationRegex.cap(1).toFloat(), + orientationRegex.cap(2).toFloat(), + orientationRegex.cap(3).toFloat())); - if (!isNaN(newOrientation.x) && !isNaN(newOrientation.y) && !isNaN(newOrientation.z)) { - emit locationChangeRequired(newPosition, true, newOrientation); + if (!isNaN(newOrientation.x) && !isNaN(newOrientation.y) && !isNaN(newOrientation.z) + && !isNaN(newOrientation.w)) { + emit locationChangeRequired(newPosition, true, newOrientation, false); return true; } else { qDebug() << "Orientation parsed from lookup string is invalid. Will not use for location change."; } } - emit locationChangeRequired(newPosition, false, newOrientation); + emit locationChangeRequired(newPosition, false, newOrientation, false); } else { qDebug() << "Could not jump to position from lookup string because it has an invalid value."; diff --git a/libraries/networking/src/AddressManager.h b/libraries/networking/src/AddressManager.h index e77fed67dc..ef97b59a1b 100644 --- a/libraries/networking/src/AddressManager.h +++ b/libraries/networking/src/AddressManager.h @@ -40,7 +40,9 @@ signals: void lookupResultIsOffline(); void lookupResultIsNotFound(); void possibleDomainChangeRequired(const QString& newHostname); - void locationChangeRequired(const glm::vec3& newPosition, bool hasOrientationChange, const glm::vec3& newOrientation); + void locationChangeRequired(const glm::vec3& newPosition, + bool hasOrientationChange, const glm::quat& newOrientation, + bool shouldFaceLocation); private: const JSONCallbackParameters& apiCallbackParameters(); diff --git a/libraries/shared/src/GLMHelpers.cpp b/libraries/shared/src/GLMHelpers.cpp index 0c7f126893..59ac84a856 100644 --- a/libraries/shared/src/GLMHelpers.cpp +++ b/libraries/shared/src/GLMHelpers.cpp @@ -284,6 +284,11 @@ QByteArray createByteArray(const glm::vec3& vector) { return QByteArray::number(vector.x) + ',' + QByteArray::number(vector.y) + ',' + QByteArray::number(vector.z); } +QByteArray createByteArray(const glm::quat& quat) { + return QByteArray::number(quat.x) + ',' + QByteArray::number(quat.y) + "," + QByteArray::number(quat.z) + "," + + QByteArray::number(quat.w); +} + bool isSimilarOrientation(const glm::quat& orientionA, const glm::quat& orientionB, float similarEnough) { // Compute the angular distance between the two orientations float angleOrientation = orientionA == orientionB ? 0.0f : glm::degrees(glm::angle(orientionA * glm::inverse(orientionB))); diff --git a/libraries/shared/src/GLMHelpers.h b/libraries/shared/src/GLMHelpers.h index 43a1d09722..296d6bcd46 100644 --- a/libraries/shared/src/GLMHelpers.h +++ b/libraries/shared/src/GLMHelpers.h @@ -77,6 +77,7 @@ float extractUniformScale(const glm::mat4& matrix); float extractUniformScale(const glm::vec3& scale); QByteArray createByteArray(const glm::vec3& vector); +QByteArray createByteArray(const glm::quat& quat); /// \return bool are two orientations similar to each other const float ORIENTATION_SIMILAR_ENOUGH = 5.0f; // 10 degrees in any direction From 866f2005bd2ccd13c083560226842c34504870fc Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 16 Sep 2014 10:08:21 -0700 Subject: [PATCH 3/3] handle case where a location should be faced --- interface/src/avatar/MyAvatar.cpp | 1 + libraries/networking/src/AddressManager.cpp | 10 ++++++---- libraries/networking/src/AddressManager.h | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 66a867ec0f..9eb6589306 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1783,6 +1783,7 @@ void MyAvatar::goToLocation(const glm::vec3& newPosition, glm::quat quatOrientation = newOrientation; if (shouldFaceLocation) { + quatOrientation = newOrientation * glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f)); // move the user a couple units away diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index 400121a49b..8ea6d1107a 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -132,9 +132,11 @@ void AddressManager::handleAPIResponse(const QJsonObject &jsonObject) { returnedPath = domainObject[LOCATION_KEY].toObject()[LOCATION_PATH_KEY].toString(); } + bool shouldFaceViewpoint = dataObject.contains(ADDRESS_API_ONLINE_KEY); + if (!returnedPath.isEmpty()) { // try to parse this returned path as a viewpoint, that's the only thing it could be for now - if (!handleRelativeViewpoint(returnedPath)) { + if (!handleRelativeViewpoint(returnedPath, shouldFaceViewpoint)) { qDebug() << "Received a location path that was could not be handled as a viewpoint -" << returnedPath; } } @@ -191,7 +193,7 @@ bool AddressManager::handleNetworkAddress(const QString& lookupString) { return false; } -bool AddressManager::handleRelativeViewpoint(const QString& lookupString) { +bool AddressManager::handleRelativeViewpoint(const QString& lookupString, bool shouldFace) { const QString FLOAT_REGEX_STRING = "([-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?)"; const QString SPACED_COMMA_REGEX_STRING = "\\s*,\\s*"; const QString POSITION_REGEX_STRING = QString("\\/") + FLOAT_REGEX_STRING + SPACED_COMMA_REGEX_STRING + @@ -224,14 +226,14 @@ bool AddressManager::handleRelativeViewpoint(const QString& lookupString) { if (!isNaN(newOrientation.x) && !isNaN(newOrientation.y) && !isNaN(newOrientation.z) && !isNaN(newOrientation.w)) { - emit locationChangeRequired(newPosition, true, newOrientation, false); + emit locationChangeRequired(newPosition, true, newOrientation, shouldFace); return true; } else { qDebug() << "Orientation parsed from lookup string is invalid. Will not use for location change."; } } - emit locationChangeRequired(newPosition, false, newOrientation, false); + emit locationChangeRequired(newPosition, false, newOrientation, shouldFace); } else { qDebug() << "Could not jump to position from lookup string because it has an invalid value."; diff --git a/libraries/networking/src/AddressManager.h b/libraries/networking/src/AddressManager.h index ef97b59a1b..2590e8f80c 100644 --- a/libraries/networking/src/AddressManager.h +++ b/libraries/networking/src/AddressManager.h @@ -49,7 +49,7 @@ private: bool handleUrl(const QUrl& lookupUrl); bool handleNetworkAddress(const QString& lookupString); - bool handleRelativeViewpoint(const QString& pathSubsection); + bool handleRelativeViewpoint(const QString& pathSubsection, bool shouldFace = false); bool handleUsername(const QString& lookupString); };