From 319d1f67959922a2cd47d6b9ef7779aedfca7913 Mon Sep 17 00:00:00 2001 From: Jose Carlos Date: Wed, 12 Feb 2014 00:54:50 +0100 Subject: [PATCH] Wired up the send of the display data to the servers Added the renderDisplayName in Avatar --- interface/src/Menu.cpp | 7 ++ interface/src/avatar/Avatar.cpp | 113 ++++++++++++++++++++++--- interface/src/avatar/Avatar.h | 8 ++ interface/src/avatar/AvatarManager.cpp | 86 ------------------- libraries/avatars/src/AvatarData.cpp | 18 +++- libraries/avatars/src/AvatarData.h | 3 + 6 files changed, 135 insertions(+), 100 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 49c2df15c3..6dbbf176ee 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -858,7 +858,14 @@ void Menu::editPreferences() { applicationInstance->getAvatar()->setSkeletonModelURL(skeletonModelURL); shouldDispatchIdentityPacket = true; } + + QString displayNameStr(displayNameEdit->text()); + if (displayNameStr != displayNameString) { + applicationInstance->getAvatar()->setDisplayName(displayNameStr); + shouldDispatchIdentityPacket = true; + } + if (shouldDispatchIdentityPacket) { applicationInstance->getAvatar()->sendIdentityPacket(); } diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 131eb4d37f..dc92d1eed9 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -28,6 +28,7 @@ #include "devices/OculusManager.h" #include "ui/TextRenderer.h" + using namespace std; const glm::vec3 DEFAULT_UP_DIRECTION(0.0f, 1.0f, 0.0f); @@ -74,7 +75,8 @@ Avatar::Avatar() : _mouseRayDirection(0.0f, 0.0f, 0.0f), _moving(false), _owningAvatarMixer(), - _initialized(false) + _initialized(false), + _displayNameWidth(0) { // we may have been created in the network thread, but we live in the main thread moveToThread(Application::getInstance()->thread()); @@ -82,6 +84,8 @@ Avatar::Avatar() : // give the pointer to our head to inherited _headData variable from AvatarData _headData = &_head; _handData = &_hand; + + } Avatar::~Avatar() { @@ -145,22 +149,27 @@ void Avatar::setMouseRay(const glm::vec3 &origin, const glm::vec3 &direction) { _mouseRayDirection = direction; } -static TextRenderer* textRenderer() { +static TextRenderer* chatTextRenderer() { static TextRenderer* renderer = new TextRenderer(SANS_FONT_FAMILY, 24, -1, false, TextRenderer::SHADOW_EFFECT); return renderer; } +static TextRenderer* displayNameTextRenderer() { + static TextRenderer* renderer = new TextRenderer(SANS_FONT_FAMILY, 12, -1, false, TextRenderer::SHADOW_EFFECT); + return renderer; +} + void Avatar::render(bool forceRenderHead) { - + { // glow when moving in the distance glm::vec3 toTarget = _position - Application::getInstance()->getAvatar()->getPosition(); const float GLOW_DISTANCE = 5.0f; Glower glower(_moving && glm::length(toTarget) > GLOW_DISTANCE ? 1.0f : 0.0f); - + // render body renderBody(forceRenderHead); - + // render sphere when far away const float MAX_ANGLE = 10.f; float height = getHeight(); @@ -176,13 +185,15 @@ void Avatar::render(bool forceRenderHead) { glPopMatrix(); } } - - + + // render display name + renderDisplayName(); + if (!_chatMessage.empty()) { int width = 0; int lastWidth = 0; for (string::iterator it = _chatMessage.begin(); it != _chatMessage.end(); it++) { - width += (lastWidth = textRenderer()->computeWidth(*it)); + width += (lastWidth = chatTextRenderer()->computeWidth(*it)); } glPushMatrix(); @@ -201,7 +212,7 @@ void Avatar::render(bool forceRenderHead) { glDisable(GL_LIGHTING); glDepthMask(false); if (_keyState == NO_KEY_DOWN) { - textRenderer()->draw(-width / 2.0f, 0, _chatMessage.c_str()); + chatTextRenderer()->draw(-width / 2.0f, 0, _chatMessage.c_str()); } else { // rather than using substr and allocating a new string, just replace the last @@ -209,10 +220,10 @@ void Avatar::render(bool forceRenderHead) { int lastIndex = _chatMessage.size() - 1; char lastChar = _chatMessage[lastIndex]; _chatMessage[lastIndex] = '\0'; - textRenderer()->draw(-width / 2.0f, 0, _chatMessage.c_str()); + chatTextRenderer()->draw(-width / 2.0f, 0, _chatMessage.c_str()); _chatMessage[lastIndex] = lastChar; glColor3f(0, 1, 0); - textRenderer()->draw(width / 2.0f - lastWidth, 0, _chatMessage.c_str() + lastIndex); + chatTextRenderer()->draw(width / 2.0f - lastWidth, 0, _chatMessage.c_str() + lastIndex); } glEnable(GL_LIGHTING); glDepthMask(true); @@ -248,6 +259,77 @@ void Avatar::renderBody(bool forceRenderHead) { _hand.render(false); } +void Avatar::renderDisplayName() { + + if (_displayNameStr.isEmpty()) { + return; + } + + glm::vec3 textPosition = _head.getPosition(); //+ glm::vec3(0,50,0); + glPushMatrix(); + glDepthMask(false); + + glm::dmat4 modelViewMatrix2; + glGetDoublev(GL_MODELVIEW_MATRIX, (GLdouble*)&modelViewMatrix2); + glTranslatef(textPosition.x, textPosition.y, textPosition.z); + // Extract rotation matrix from the modelview matrix + glm::dmat4 modelViewMatrix; + glGetDoublev(GL_MODELVIEW_MATRIX, (GLdouble*)&modelViewMatrix); + + // Delete rotation info + modelViewMatrix[0][0] = modelViewMatrix[1][1] = modelViewMatrix[2][2] = 1.0; + modelViewMatrix[0][1] = modelViewMatrix[0][2] = 0.0; + modelViewMatrix[1][0] = modelViewMatrix[1][2] = 0.0; + modelViewMatrix[2][0] = modelViewMatrix[2][1] = 0.0; + + glLoadMatrixd((GLdouble*)&modelViewMatrix); // Override current matrix with our own + glScalef(1.0, -1.0, 1.0); // TextRenderer::draw paints the text upside down. This fixes that + + // We need to compute the scale factor such as the text remains with fixed size respect to window coordinates + // We project y = 0 and y = 1 and check the difference in projection coordinates + GLdouble projectionMatrix[16]; + GLint viewportMatrix[4]; + GLdouble result0[3]; + GLdouble result1[3]; + + glm::dvec3 upVector(modelViewMatrix2[1]); + glGetDoublev(GL_PROJECTION_MATRIX, (GLdouble*)&projectionMatrix); + glGetIntegerv(GL_VIEWPORT, viewportMatrix); + + glm::dvec3 testPoint0 = glm::dvec3(textPosition); + glm::dvec3 testPoint1 = glm::dvec3(textPosition) + upVector; + + bool success; + success = gluProject(testPoint0.x, testPoint0.y, testPoint0.z, + (GLdouble*)&modelViewMatrix2, projectionMatrix, viewportMatrix, + &result0[0], &result0[1], &result0[2]); + success = success && + gluProject(testPoint1.x, testPoint1.y, testPoint1.z, + (GLdouble*)&modelViewMatrix2, projectionMatrix, viewportMatrix, + &result1[0], &result1[1], &result1[2]); + + if (success) { + double textWindowHeight = abs(result1[1] - result0[1]); + float textScale = 1.0; + float scaleFactor = 1.0; + if (textWindowHeight > EPSILON) { + scaleFactor = textScale / textWindowHeight; + } + + glScalef(scaleFactor, scaleFactor, 1.0); + + glColor3f(0.93, 0.93, 0.93); + + // TextRenderer, based on QT opengl text rendering functions + + QByteArray ba = _displayNameStr.toLocal8Bit(); + const char *text = ba.data(); + displayNameTextRenderer()->draw(-_displayNameWidth/2.0, 0, text); + } + glDepthMask(true); + glPopMatrix(); +} + bool Avatar::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance) const { float minDistance = FLT_MAX; float modelDistance; @@ -346,6 +428,15 @@ void Avatar::setSkeletonModelURL(const QUrl &skeletonModelURL) { _skeletonModel.setURL(skeletonModelURL); } +void Avatar::setDisplayName(const QString& displayName) { + AvatarData::setDisplayNameStr(displayName); + int width = 0; + for (int i = 0; i < displayName.size(); i++) { + width += (displayNameTextRenderer()->computeWidth(displayName[i].toLatin1())); + } + _displayNameWidth = width; +} + int Avatar::parseData(const QByteArray& packet) { // change in position implies movement glm::vec3 oldPosition = _position; diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index dfe72fdc18..41b821838c 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -21,6 +21,7 @@ #include "SkeletonModel.h" #include "world.h" + static const float SCALING_RATIO = .05f; static const float SMOOTHING_RATIO = .05f; // 0 < ratio < 1 static const float RESCALING_TOLERANCE = .02f; @@ -114,6 +115,7 @@ public: virtual void setFaceModelURL(const QUrl& faceModelURL); virtual void setSkeletonModelURL(const QUrl& skeletonModelURL); + virtual void setDisplayName(const QString& displayName); int parseData(const QByteArray& packet); @@ -152,7 +154,13 @@ private: bool _initialized; + int _displayNameWidth; + + + void renderBody(bool forceRenderHead); + + void renderDisplayName(); }; #endif diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index c9b84a15df..a03492bc9b 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -75,93 +75,7 @@ void AvatarManager::renderAvatars(bool forceRenderHead, bool selfAvatarOnly) { "Application::renderAvatars()"); bool renderLookAtVectors = Menu::getInstance()->isOptionChecked(MenuOption::LookAtVectors); - // ------------------------------------------------------------------------------------- - // Josecpujol(begin): test code, as I dont seem to get any avatar. Render some text here - // ------------------------------------------------------------------------------------- - glm::dvec3 textPosition(100.0, 50.0, 100.0); - std::string text("my string"); - - // Draw a fake avatar - glPushMatrix(); - glColor3f(1.0,0,0); - double radius = 10.0; - glTranslated(textPosition.x, textPosition.y - 2 * radius, textPosition.z); - glutSolidSphere(radius, 10, 10); - glPopMatrix(); - - // Draw a mark where the text should be - glPushMatrix(); - glColor3f(1.0,1.0,0); - glTranslated(textPosition.x, textPosition.y, textPosition.z); - glutSolidSphere(1.0, 10, 10); - glPopMatrix(); - - glPushMatrix(); - glm::dmat4 modelViewMatrix2; - glGetDoublev(GL_MODELVIEW_MATRIX, (GLdouble*)&modelViewMatrix2); - glTranslated(textPosition.x, textPosition.y, textPosition.z); - // Extract rotation matrix from the modelview matrix - glm::dmat4 modelViewMatrix; - glGetDoublev(GL_MODELVIEW_MATRIX, (GLdouble*)&modelViewMatrix); - // Delete rotation info - modelViewMatrix[0][0] = modelViewMatrix[1][1] = modelViewMatrix[2][2] = 1.0; - modelViewMatrix[0][1] = modelViewMatrix[0][2] = 0.0; - modelViewMatrix[1][0] = modelViewMatrix[1][2] = 0.0; - modelViewMatrix[2][0] = modelViewMatrix[2][1] = 0.0; - - glLoadMatrixd((GLdouble*)&modelViewMatrix); // Override current matrix with our own - glScalef(1.0, -1.0, 1.0); // TextRenderer::draw paints the text upside down. This fixes that - - // We need to compute the scale factor such as the text remains with fixed size respect to window coordinates - // We project y = 0 and y = 1 and check the difference in projection coordinates - GLdouble projectionMatrix[16]; - GLint viewportMatrix[4]; - GLdouble result0[3]; - GLdouble result1[3]; - - glm::dvec3 upVector(modelViewMatrix2[1]); - glGetDoublev(GL_PROJECTION_MATRIX, (GLdouble*)&projectionMatrix); - glGetIntegerv(GL_VIEWPORT, viewportMatrix); - - glm::dvec3 testPoint0 = textPosition; - glm::dvec3 testPoint1 = textPosition + upVector; - - bool success; - success = gluProject(testPoint0.x, testPoint0.y, testPoint0.z, - (GLdouble*)&modelViewMatrix2, projectionMatrix, viewportMatrix, - &result0[0], &result0[1], &result0[2]); - success = success && - gluProject(testPoint1.x, testPoint1.y, testPoint1.z, - (GLdouble*)&modelViewMatrix2, projectionMatrix, viewportMatrix, - &result1[0], &result1[1], &result1[2]); - - if (success) { - double textWindowHeight = abs(result1[1] - result0[1]); - float textScale = 1.0; - float scaleFactor = textScale / textWindowHeight; - - glScalef(scaleFactor, scaleFactor, 1.0); - - glColor3f(0.93, 0.93, 0.93); - - // TextRenderer, based on QT opengl text rendering functions - TextRenderer* textRenderer = new TextRenderer(SANS_FONT_FAMILY, 12, -1, false, TextRenderer::NO_EFFECT); - int width = 0; - for (std::string::iterator it = text.begin(); it != text.end(); it++) { - width += (textRenderer->computeWidth(*it)); - } - textRenderer->draw(-width/2.0, 0, text.c_str()); - delete textRenderer; - } - - glPopMatrix(); - - // ------------------------------------------------------------------------------------- - // josecpujol(end) - // ------------------------------------------------------------------------------------- - - if (!selfAvatarOnly) { foreach (const AvatarSharedPointer& avatarPointer, _avatarHash) { diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index b2cd1cf076..3c711dc127 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -274,7 +274,8 @@ bool AvatarData::hasIdentityChangedAfterParsing(const QByteArray &packet) { QUuid avatarUUID; QUrl faceModelURL, skeletonModelURL; - packetStream >> avatarUUID >> faceModelURL >> skeletonModelURL; + QString displayNameStr; + packetStream >> avatarUUID >> faceModelURL >> skeletonModelURL >> displayNameStr; bool hasIdentityChanged = false; @@ -287,7 +288,12 @@ bool AvatarData::hasIdentityChangedAfterParsing(const QByteArray &packet) { setSkeletonModelURL(skeletonModelURL); hasIdentityChanged = true; } - + + if (displayNameStr != _displayNameStr) { + setDisplayNameStr(displayNameStr); + hasIdentityChanged = true; + } + return hasIdentityChanged; } @@ -295,7 +301,7 @@ QByteArray AvatarData::identityByteArray() { QByteArray identityData; QDataStream identityStream(&identityData, QIODevice::Append); - identityStream << QUuid() << _faceModelURL << _skeletonModelURL; + identityStream << QUuid() << _faceModelURL << _skeletonModelURL << _displayNameStr; return identityData; } @@ -310,6 +316,12 @@ void AvatarData::setSkeletonModelURL(const QUrl& skeletonModelURL) { _skeletonModelURL = skeletonModelURL; } +void AvatarData::setDisplayNameStr(const QString& displayName) { + qDebug() << "Changing display name for avatar to" << displayName; + _displayNameStr = displayName; +} + + void AvatarData::setClampedTargetScale(float targetScale) { targetScale = glm::clamp(targetScale, MIN_AVATAR_SCALE, MAX_AVATAR_SCALE); diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 5c3c9ad9af..4fc4e1f4f7 100755 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -149,8 +149,10 @@ public: const QUrl& getFaceModelURL() const { return _faceModelURL; } const QUrl& getSkeletonModelURL() const { return _skeletonModelURL; } + const QString& getDisplayNameStr() const { return _displayNameStr; } virtual void setFaceModelURL(const QUrl& faceModelURL); virtual void setSkeletonModelURL(const QUrl& skeletonModelURL); + virtual void setDisplayNameStr(const QString& displayName); protected: glm::vec3 _position; @@ -180,6 +182,7 @@ protected: QUrl _faceModelURL; QUrl _skeletonModelURL; + QString _displayNameStr; private: // privatize the copy constructor and assignment operator so they cannot be called AvatarData(const AvatarData&);