From 0011276b0bc1e6aab7b8854d39acae874a19261d Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 7 Apr 2014 14:19:17 -0700 Subject: [PATCH 1/2] Added back the download stats, which got lost in a merge. --- interface/src/ui/Stats.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index 1722732e76..dbcbb3d8bb 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -20,6 +20,8 @@ #include "Menu.h" #include "Util.h" +using namespace std; + const int STATS_PELS_PER_LINE = 20; const int STATS_GENERAL_MIN_WIDTH = 165; @@ -287,7 +289,7 @@ void Stats::display( MyAvatar* myAvatar = Application::getInstance()->getAvatar(); glm::vec3 avatarPos = myAvatar->getPosition(); - lines = _expanded ? 4 : 3; + lines = _expanded ? 5 : 3; drawBackground(backgroundColor, horizontalOffset, 0, _geoStatsWidth, lines * STATS_PELS_PER_LINE + 10); horizontalOffset += 5; @@ -318,6 +320,16 @@ void Stats::display( verticalOffset += STATS_PELS_PER_LINE; drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, avatarMixerStats, color); + + stringstream downloads; + downloads << "Downloads: "; + foreach (Resource* resource, ResourceCache::getLoadingRequests()) { + downloads << (int)(resource->getProgress() * 100.0f) << "% "; + } + downloads << "(" << ResourceCache::getPendingRequestCount() << " pending)"; + + verticalOffset += STATS_PELS_PER_LINE; + drawText(horizontalOffset, verticalOffset, 0.10f, 0.f, 2.f, downloads.str().c_str(), color); } verticalOffset = 0; From fa05a482707a049c53ac554aede2b7190579b87c Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 7 Apr 2014 17:55:36 -0700 Subject: [PATCH 2/2] Provide a means of supplying the joint mappings in the FST file so that agent scripts can address joints by name. Closes #2526. --- examples/crazylegs.js | 7 +++-- interface/src/avatar/Avatar.cpp | 4 +++ interface/src/avatar/Avatar.h | 2 ++ libraries/avatars/src/AvatarData.cpp | 46 ++++++++++++++++++++++++++++ libraries/avatars/src/AvatarData.h | 12 ++++++-- 5 files changed, 67 insertions(+), 4 deletions(-) diff --git a/examples/crazylegs.js b/examples/crazylegs.js index 099387e000..19a171dbdf 100644 --- a/examples/crazylegs.js +++ b/examples/crazylegs.js @@ -12,9 +12,12 @@ var AMPLITUDE = 45.0; var cumulativeTime = 0.0; -print("Joint List:"); +print("# Joint list start"); var jointList = MyAvatar.getJointNames(); -print(jointList); +for (var i = 0; i < jointList.length; i++) { + print("jointIndex = " + jointList[i] + " = " + i); +} +print("# Joint list end"); Script.update.connect(function(deltaTime) { cumulativeTime += deltaTime; diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 899514d1c1..7a55d4d534 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -331,6 +331,10 @@ void Avatar::renderBody(RenderMode renderMode) { getHand()->render(false); } +void Avatar::updateJointMappings() { + // no-op; joint mappings come from skeleton model +} + void Avatar::renderBillboard() { if (_billboard.isEmpty()) { return; diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index f6d5669859..e0d46c8624 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -187,6 +187,8 @@ protected: void renderDisplayName(); virtual void renderBody(RenderMode renderMode); + virtual void updateJointMappings(); + private: bool _initialized; diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 930e3f7350..e84636b5a4 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -639,6 +639,8 @@ void AvatarData::setSkeletonModelURL(const QUrl& skeletonModelURL) { _skeletonModelURL = skeletonModelURL.isEmpty() ? DEFAULT_BODY_MODEL_URL : skeletonModelURL; qDebug() << "Changing skeleton model for avatar to" << _skeletonModelURL.toString(); + + updateJointMappings(); } void AvatarData::setDisplayName(const QString& displayName) { @@ -673,6 +675,40 @@ void AvatarData::setBillboardFromURL(const QString &billboardURL) { void AvatarData::setBillboardFromNetworkReply() { QNetworkReply* networkReply = reinterpret_cast(sender()); setBillboard(networkReply->readAll()); + networkReply->deleteLater(); +} + +void AvatarData::setJointMappingsFromNetworkReply() { + QNetworkReply* networkReply = static_cast(sender()); + + QByteArray line; + while (!(line = networkReply->readLine()).isEmpty()) { + if (!(line = line.trimmed()).startsWith("jointIndex")) { + continue; + } + int jointNameIndex = line.indexOf('=') + 1; + if (jointNameIndex == 0) { + continue; + } + int secondSeparatorIndex = line.indexOf('=', jointNameIndex); + if (secondSeparatorIndex == -1) { + continue; + } + QString jointName = line.mid(jointNameIndex, secondSeparatorIndex - jointNameIndex).trimmed(); + bool ok; + int jointIndex = line.mid(secondSeparatorIndex + 1).trimmed().toInt(&ok); + if (ok) { + while (_jointNames.size() < jointIndex + 1) { + _jointNames.append(QString()); + } + _jointNames[jointIndex] = jointName; + } + } + for (int i = 0; i < _jointNames.size(); i++) { + _jointIndices.insert(_jointNames.at(i), i + 1); + } + + networkReply->deleteLater(); } void AvatarData::setClampedTargetScale(float targetScale) { @@ -705,3 +741,13 @@ void AvatarData::sendBillboardPacket() { NodeList::getInstance()->broadcastToNodes(billboardPacket, NodeSet() << NodeType::AvatarMixer); } } + +void AvatarData::updateJointMappings() { + _jointIndices.clear(); + _jointNames.clear(); + + if (networkAccessManager && _skeletonModelURL.fileName().toLower().endsWith(".fst")) { + QNetworkReply* networkReply = networkAccessManager->get(QNetworkRequest(_skeletonModelURL)); + connect(networkReply, SIGNAL(finished()), this, SLOT(setJointMappingsFromNetworkReply())); + } +} diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 221bbd0428..cf645855e8 100755 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -30,6 +30,7 @@ typedef unsigned long long quint64; #include #include +#include #include #include #include @@ -160,9 +161,9 @@ public: Q_INVOKABLE glm::quat getJointRotation(const QString& name) const; /// Returns the index of the joint with the specified name, or -1 if not found/unknown. - Q_INVOKABLE virtual int getJointIndex(const QString& name) const { return -1; } + Q_INVOKABLE virtual int getJointIndex(const QString& name) const { return _jointIndices.value(name) - 1; } - Q_INVOKABLE virtual QStringList getJointNames() const { return QStringList(); } + Q_INVOKABLE virtual QStringList getJointNames() const { return _jointNames; } // key state void setKeyState(KeyState s) { _keyState = s; } @@ -217,6 +218,7 @@ public slots: void sendIdentityPacket(); void sendBillboardPacket(); void setBillboardFromNetworkReply(); + void setJointMappingsFromNetworkReply(); protected: glm::vec3 _position; glm::vec3 _handPosition; @@ -258,10 +260,16 @@ protected: QByteArray _billboard; QString _billboardURL; + QHash _jointIndices; ///< 1-based, since zero is returned for missing keys + QStringList _jointNames; ///< in order of depth-first traversal + static QNetworkAccessManager* networkAccessManager; quint64 _errorLogExpiry; ///< time in future when to log an error + /// Loads the joint indices, names from the FST file (if any) + virtual void updateJointMappings(); + private: // privatize the copy constructor and assignment operator so they cannot be called AvatarData(const AvatarData&);