From 0033dfe5af4bb0ff5fbca0e83572aa8d5ec7c6b4 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 16 Sep 2014 09:57:21 -0700 Subject: [PATCH] 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