Merge pull request #7171 from jherico/avatar_qml_location

Allow avatar positioning from QML
This commit is contained in:
Brad Hefta-Gaub 2016-02-24 11:37:12 -08:00
commit 2a18127a01
4 changed files with 135 additions and 6 deletions

View file

@ -123,8 +123,11 @@ MyAvatar::MyAvatar(RigPointer rig) :
}
// connect to AddressManager signal for location jumps
connect(DependencyManager::get<AddressManager>().data(), &AddressManager::locationChangeRequired,
this, &MyAvatar::goToLocation);
connect(DependencyManager::get<AddressManager>().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) {

View file

@ -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; };

View file

@ -9,10 +9,13 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include <QColor>
#include <QUrl>
#include <QUuid>
#include <QRect>
#include <QtCore/QUrl>
#include <QtCore/QUuid>
#include <QtCore/QRect>
#include <QtCore/QVariant>
#include <QtGui/QColor>
#include <QtGui/QVector3D>
#include <QtGui/QQuaternion>
#include <glm/gtc/quaternion.hpp>
#include "RegisteredMetaTypes.h"
@ -91,6 +94,51 @@ QScriptValue qVectorVec3ToScriptValue(QScriptEngine* engine, const QVector<glm::
return array;
}
glm::vec3 vec3FromVariant(const QVariant &object, bool& valid) {
glm::vec3 v;
valid = false;
if (!object.isValid() || object.isNull()) {
return v;
} else if (object.canConvert<float>()) {
v = glm::vec3(object.toFloat());
valid = true;
} else if (object.canConvert<QVector3D>()) {
auto qvec3 = qvariant_cast<QVector3D>(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<float>() && y.canConvert<float>() && z.canConvert<float>()) {
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<QQuaternion>()) {
auto qvec3 = qvariant_cast<QQuaternion>(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<glm::quat>& vector) {
QScriptValue array = engine->newArray();
for (int i = 0; i < vector.size(); i++) {

View file

@ -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);