diff --git a/interface/src/ui/overlays/ModelOverlay.cpp b/interface/src/ui/overlays/ModelOverlay.cpp index ccaa1d4fbc..e993166558 100644 --- a/interface/src/ui/overlays/ModelOverlay.cpp +++ b/interface/src/ui/overlays/ModelOverlay.cpp @@ -126,6 +126,55 @@ void ModelOverlay::setProperties(const QVariantMap& properties) { QMetaObject::invokeMethod(_model.get(), "setTextures", Qt::AutoConnection, Q_ARG(const QVariantMap&, textureMap)); } + + // relative + auto jointTranslationsValue = properties["jointTranslations"]; + if (jointTranslationsValue.canConvert(QVariant::List)) { + const QVariantList& jointTranslations = jointTranslationsValue.toList(); + int translationCount = jointTranslations.size(); + int jointCount = _model->getJointStateCount(); + if (translationCount < jointCount) { + jointCount = translationCount; + } + for (int i=0; i < jointCount; i++) { + const auto& translationValue = jointTranslations[i]; + if (translationValue.isValid()) { + _model->setJointTranslation(i, true, vec3FromVariant(translationValue), 1.0f); + } + } + _updateModel = true; + } + + // relative + auto jointRotationsValue = properties["jointRotations"]; + if (jointRotationsValue.canConvert(QVariant::List)) { + const QVariantList& jointRotations = jointRotationsValue.toList(); + int rotationCount = jointRotations.size(); + int jointCount = _model->getJointStateCount(); + if (rotationCount < jointCount) { + jointCount = rotationCount; + } + for (int i=0; i < jointCount; i++) { + const auto& rotationValue = jointRotations[i]; + if (rotationValue.isValid()) { + _model->setJointRotation(i, true, quatFromVariant(rotationValue), 1.0f); + } + } + _updateModel = true; + } +} + +template +vectorType ModelOverlay::mapJoints(mapFunction function) const { + vectorType result; + if (_model && _model->isActive()) { + const int jointCount = _model->getJointStateCount(); + result.reserve(jointCount); + for (int i = 0; i < jointCount; i++) { + result << function(i); + } + } + return result; } QVariant ModelOverlay::getProperty(const QString& property) { @@ -150,6 +199,58 @@ QVariant ModelOverlay::getProperty(const QString& property) { } } + if (property == "jointNames") { + if (_model && _model->isActive()) { + // note: going through Rig because Model::getJointNames() (which proxies to FBXGeometry) was always empty + const RigPointer rig = _model->getRig(); + if (rig) { + return mapJoints([rig](int jointIndex) -> QString { + return rig->nameOfJoint(jointIndex); + }); + } + } + } + + // relative + if (property == "jointRotations") { + return mapJoints( + [this](int jointIndex) -> QVariant { + glm::quat rotation; + _model->getJointRotation(jointIndex, rotation); + return quatToVariant(rotation); + }); + } + + // relative + if (property == "jointTranslations") { + return mapJoints( + [this](int jointIndex) -> QVariant { + glm::vec3 translation; + _model->getJointTranslation(jointIndex, translation); + return vec3toVariant(translation); + }); + } + + // absolute + if (property == "jointOrientations") { + return mapJoints( + [this](int jointIndex) -> QVariant { + glm::quat orientation; + _model->getJointRotationInWorldFrame(jointIndex, orientation); + return quatToVariant(orientation); + }); + } + + // absolute + if (property == "jointPositions") { + return mapJoints( + [this](int jointIndex) -> QVariant { + glm::vec3 position; + _model->getJointPositionInWorldFrame(jointIndex, position); + return vec3toVariant(position); + }); + } + return Volume3DOverlay::getProperty(property); } diff --git a/interface/src/ui/overlays/ModelOverlay.h b/interface/src/ui/overlays/ModelOverlay.h index a3ddeed480..8afe9a20b6 100644 --- a/interface/src/ui/overlays/ModelOverlay.h +++ b/interface/src/ui/overlays/ModelOverlay.h @@ -41,6 +41,12 @@ public: void locationChanged(bool tellPhysics) override; +protected: + // helper to extract metadata from our Model's rigged joints + template using mapFunction = std::function; + template + vectorType mapJoints(mapFunction function) const; + private: ModelPointer _model;