From 2258a9cad95a553ef7b4d162bbbefaffd456d22c Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 23 Feb 2016 11:52:02 -0800 Subject: [PATCH] Allow avatar positioning from QML --- interface/src/avatar/MyAvatar.cpp | 42 ++++++++- interface/src/avatar/MyAvatar.h | 1 + libraries/shared/src/RegisteredMetaTypes.cpp | 92 +++++++++++++++++++- libraries/shared/src/RegisteredMetaTypes.h | 6 ++ 4 files changed, 135 insertions(+), 6 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 56584df44e..ae3c969d2f 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -123,8 +123,11 @@ MyAvatar::MyAvatar(RigPointer rig) : } // connect to AddressManager signal for location jumps - connect(DependencyManager::get().data(), &AddressManager::locationChangeRequired, - this, &MyAvatar::goToLocation); + connect(DependencyManager::get().data(), &AddressManager::locationChangeRequired, + [=](const glm::vec3& newPosition, bool hasOrientation, const glm::quat& newOrientation, bool shouldFaceLocation){ + goToLocation(newPosition, hasOrientation, newOrientation, shouldFaceLocation); + }); + _characterController.setEnabled(true); _bodySensorMatrix = deriveBodyFromHMDSensor(); @@ -1666,6 +1669,41 @@ void MyAvatar::resetSize() { qCDebug(interfaceapp, "Reset scale to %f", (double)_targetScale); } + +void MyAvatar::goToLocation(const QVariant& propertiesVar) { + qCDebug(interfaceapp, "MyAvatar QML goToLocation"); + auto properties = propertiesVar.toMap(); + if (!properties.contains("position")) { + qCWarning(interfaceapp, "goToLocation called without a position variable"); + return; + } + + bool validPosition; + glm::vec3 v = vec3FromVariant(properties["position"], validPosition); + if (!validPosition) { + qCWarning(interfaceapp, "goToLocation called with invalid position variable"); + return; + } + bool validOrientation; + glm::quat q; + if (properties.contains("orientation")) { + q = quatFromVariant(properties["orientation"], validOrientation); + if (!validOrientation) { + glm::vec3 eulerOrientation = vec3FromVariant(properties["orientation"], validOrientation); + q = glm::quat(eulerOrientation); + if (!validOrientation) { + qCWarning(interfaceapp, "goToLocation called with invalid orientation variable"); + } + } + } + + if (validOrientation) { + goToLocation(v, true, q); + } else { + goToLocation(v); + } +} + void MyAvatar::goToLocation(const glm::vec3& newPosition, bool hasOrientation, const glm::quat& newOrientation, bool shouldFaceLocation) { diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 8c84299e08..637baa3c22 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -253,6 +253,7 @@ public slots: void goToLocation(const glm::vec3& newPosition, bool hasOrientation = false, const glm::quat& newOrientation = glm::quat(), bool shouldFaceLocation = false); + void goToLocation(const QVariant& properties); // Set/Get update the thrust that will move the avatar around void addThrust(glm::vec3 newThrust) { _thrust += newThrust; }; diff --git a/libraries/shared/src/RegisteredMetaTypes.cpp b/libraries/shared/src/RegisteredMetaTypes.cpp index c2c35df957..a1aae35063 100644 --- a/libraries/shared/src/RegisteredMetaTypes.cpp +++ b/libraries/shared/src/RegisteredMetaTypes.cpp @@ -9,10 +9,13 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include #include #include "RegisteredMetaTypes.h" @@ -91,6 +94,51 @@ QScriptValue qVectorVec3ToScriptValue(QScriptEngine* engine, const QVector()) { + v = glm::vec3(object.toFloat()); + valid = true; + } else if (object.canConvert()) { + auto qvec3 = qvariant_cast(object); + v.x = qvec3.x(); + v.y = qvec3.y(); + v.z = qvec3.z(); + valid = true; + } else { + auto map = object.toMap(); + auto x = map["x"]; + auto y = map["y"]; + auto z = map["z"]; + if (!x.isValid()) { + x = map["width"]; + } + if (!y.isValid()) { + y = map["height"]; + } + if (!y.isValid()) { + z = map["depth"]; + } + + if (x.canConvert() && y.canConvert() && z.canConvert()) { + v.x = x.toFloat(); + v.y = y.toFloat(); + v.z = z.toFloat(); + valid = true; + } + } + return v; +} + +glm::vec3 vec3FromVariant(const QVariant &object) { + bool valid = false; + return vec3FromVariant(object, valid); +} + + QScriptValue quatToScriptValue(QScriptEngine* engine, const glm::quat &quat) { QScriptValue obj = engine->newObject(); if (quat.x != quat.x || quat.y != quat.y || quat.z != quat.z || quat.w != quat.w) { @@ -111,6 +159,42 @@ void quatFromScriptValue(const QScriptValue &object, glm::quat &quat) { quat.w = object.property("w").toVariant().toFloat(); } +glm::quat quatFromVariant(const QVariant &object, bool& isValid) { + glm::quat q; + if (object.canConvert()) { + auto qvec3 = qvariant_cast(object); + q.x = qvec3.x(); + q.y = qvec3.y(); + q.z = qvec3.z(); + q.w = qvec3.scalar(); + isValid = true; + } else { + auto map = object.toMap(); + q.x = map["x"].toFloat(&isValid); + if (!isValid) { + return glm::quat(); + } + q.y = map["y"].toFloat(&isValid); + if (!isValid) { + return glm::quat(); + } + q.z = map["z"].toFloat(&isValid); + if (!isValid) { + return glm::quat(); + } + q.w = map["w"].toFloat(&isValid); + if (!isValid) { + return glm::quat(); + } + } + return q; +} + +glm::quat quatFromVariant(const QVariant &object) { + bool valid = false; + return quatFromVariant(object, valid); +} + QScriptValue qVectorQuatToScriptValue(QScriptEngine* engine, const QVector& vector) { QScriptValue array = engine->newArray(); for (int i = 0; i < vector.size(); i++) { diff --git a/libraries/shared/src/RegisteredMetaTypes.h b/libraries/shared/src/RegisteredMetaTypes.h index 81314cef69..2bec5b025e 100644 --- a/libraries/shared/src/RegisteredMetaTypes.h +++ b/libraries/shared/src/RegisteredMetaTypes.h @@ -41,12 +41,18 @@ void vec4FromScriptValue(const QScriptValue& object, glm::vec4& vec4); QScriptValue vec3toScriptValue(QScriptEngine* engine, const glm::vec3 &vec3); void vec3FromScriptValue(const QScriptValue &object, glm::vec3 &vec3); +glm::vec3 vec3FromVariant(const QVariant &object, bool& valid); +glm::vec3 vec3FromVariant(const QVariant &object); + QScriptValue vec2toScriptValue(QScriptEngine* engine, const glm::vec2 &vec2); void vec2FromScriptValue(const QScriptValue &object, glm::vec2 &vec2); QScriptValue quatToScriptValue(QScriptEngine* engine, const glm::quat& quat); void quatFromScriptValue(const QScriptValue &object, glm::quat& quat); +glm::quat quatFromVariant(const QVariant &object, bool& isValid); +glm::quat quatFromVariant(const QVariant &object); + QScriptValue qRectToScriptValue(QScriptEngine* engine, const QRect& rect); void qRectFromScriptValue(const QScriptValue& object, QRect& rect);