diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index bdffcd1dec..bffaa06cb0 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -653,6 +653,9 @@ void Application::updateProjectionMatrix(Camera& camera, bool updateViewFrustum) } glFrustum(left, right, bottom, top, nearVal, farVal); + // save matrix + glGetFloatv(GL_PROJECTION_MATRIX, (GLfloat*)&_projectionMatrix); + glMatrixMode(GL_MODELVIEW); } @@ -2961,6 +2964,15 @@ void Application::loadTranslatedViewMatrix(const glm::vec3& translation) { translation.z + _viewMatrixTranslation.z); } +void Application::getModelViewMatrix(glm::dmat4* modelViewMatrix) { + (*modelViewMatrix) =_untranslatedViewMatrix; + (*modelViewMatrix)[3] = _untranslatedViewMatrix * glm::vec4(_viewMatrixTranslation, 1); +} + +void Application::getProjectionMatrix(glm::dmat4* projectionMatrix) { + *projectionMatrix = _projectionMatrix; +} + void Application::computeOffAxisFrustum(float& left, float& right, float& bottom, float& top, float& nearVal, float& farVal, glm::vec4& nearClipPlane, glm::vec4& farClipPlane) const { diff --git a/interface/src/Application.h b/interface/src/Application.h index 06a19f13b1..d80cd6b661 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -193,6 +193,9 @@ public: const glm::mat4& getShadowMatrix() const { return _shadowMatrix; } + void getModelViewMatrix(glm::dmat4* modelViewMatrix); + void getProjectionMatrix(glm::dmat4* projectionMatrix); + /// Computes the off-axis frustum parameters for the view frustum, taking mirroring into account. void computeOffAxisFrustum(float& left, float& right, float& bottom, float& top, float& nearVal, float& farVal, glm::vec4& nearClipPlane, glm::vec4& farClipPlane) const; @@ -398,6 +401,7 @@ private: glm::mat4 _untranslatedViewMatrix; glm::vec3 _viewMatrixTranslation; + glm::mat4 _projectionMatrix; glm::mat4 _shadowMatrix; diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 5b92630d91..327f905194 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -785,6 +785,11 @@ void Menu::editPreferences() { skeletonURLEdit->setPlaceholderText(DEFAULT_BODY_MODEL_URL.toString()); form->addRow("Skeleton URL:", skeletonURLEdit); + QString displayNameString = applicationInstance->getAvatar()->getDisplayName(); + QLineEdit* displayNameEdit = new QLineEdit(displayNameString); + displayNameEdit->setMinimumWidth(QLINE_MINIMUM_WIDTH); + form->addRow("Display name:", displayNameEdit); + QSlider* pupilDilation = new QSlider(Qt::Horizontal); pupilDilation->setValue(applicationInstance->getAvatar()->getHead()->getPupilDilation() * pupilDilation->maximum()); form->addRow("Pupil Dilation:", pupilDilation); @@ -857,7 +862,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 cea6a5029f..9ff1ec8cb1 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -56,6 +56,9 @@ const float HEAD_RATE_MAX = 50.f; const int NUM_BODY_CONE_SIDES = 9; const float CHAT_MESSAGE_SCALE = 0.0015f; const float CHAT_MESSAGE_HEIGHT = 0.1f; +const float DISPLAYNAME_FADE_TIME = 0.5f; +const float DISPLAYNAME_FADE_FACTOR = pow(0.01f, 1.0f / DISPLAYNAME_FADE_TIME); +const float DISPLAYNAME_ALPHA = 0.95f; Avatar::Avatar() : AvatarData(), @@ -107,7 +110,7 @@ void Avatar::simulate(float deltaTime) { if (_scale != _targetScale) { setScale(_targetScale); } - + // copy velocity so we can use it later for acceleration glm::vec3 oldVelocity = getVelocity(); @@ -135,7 +138,23 @@ void Avatar::simulate(float deltaTime) { // Zero thrust out now that we've added it to velocity in this frame _thrust = glm::vec3(0, 0, 0); - + + // update animation for display name fade in/out + if ( _displayNameTargetAlpha != _displayNameAlpha) { + // the alpha function is + // Fade out => alpha(t) = factor ^ t => alpha(t+dt) = alpha(t) * factor^(dt) + // Fade in => alpha(t) = 1 - factor^t => alpha(t+dt) = 1-(1-alpha(t))*coef^(dt) + // factor^(dt) = coef + float coef = pow(DISPLAYNAME_FADE_FACTOR, deltaTime); + if (_displayNameTargetAlpha < _displayNameAlpha) { + // Fading out + _displayNameAlpha *= coef; + } else { + // Fading in + _displayNameAlpha = 1 - (1 - _displayNameAlpha) * coef; + } + _displayNameAlpha = abs(_displayNameAlpha - _displayNameTargetAlpha) < 0.01? _displayNameTargetAlpha : _displayNameAlpha; + } } void Avatar::setMouseRay(const glm::vec3 &origin, const glm::vec3 &direction) { @@ -143,19 +162,35 @@ void Avatar::setMouseRay(const glm::vec3 &origin, const glm::vec3 &direction) { _mouseRayDirection = direction; } -static TextRenderer* textRenderer() { - static TextRenderer* renderer = new TextRenderer(SANS_FONT_FAMILY, 24, -1, false, TextRenderer::SHADOW_EFFECT); - return renderer; +enum TextRendererType { + CHAT, + DISPLAYNAME +}; + +static TextRenderer* textRenderer(TextRendererType type) { + static TextRenderer* chatRenderer = new TextRenderer(SANS_FONT_FAMILY, 24, -1, false, TextRenderer::SHADOW_EFFECT); + static TextRenderer* displayNameRenderer = new TextRenderer(SANS_FONT_FAMILY, 12, -1, false, TextRenderer::NO_EFFECT); + + switch(type) { + case CHAT: + return chatRenderer; + case DISPLAYNAME: + return displayNameRenderer; + } + + return displayNameRenderer; } void Avatar::render(bool forceRenderHead) { - + glm::vec3 toTarget = _position - Application::getInstance()->getAvatar()->getPosition(); + float lengthToTarget = glm::length(toTarget); + { // 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); + const float GLOW_DISTANCE = 5.0f; + Glower glower(_moving && lengthToTarget > GLOW_DISTANCE ? 1.0f : 0.0f); + // render body if (Menu::getInstance()->isOptionChecked(MenuOption::RenderSkeletonCollisionProxies)) { _skeletonModel.renderCollisionProxies(0.7f); @@ -166,10 +201,10 @@ void Avatar::render(bool forceRenderHead) { if (Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) { renderBody(forceRenderHead); } - + // render sphere when far away const float MAX_ANGLE = 10.f; - float height = getHeight(); + float height = getSkeletonHeight(); glm::vec3 delta = height * (getHead()->getCameraOrientation() * IDENTITY_UP) / 2.f; float angle = abs(angleBetween(toTarget + delta, toTarget - delta)); @@ -182,13 +217,15 @@ void Avatar::render(bool forceRenderHead) { glPopMatrix(); } } + const float DISPLAYNAME_DISTANCE = 4.0f; + setShowDisplayName(lengthToTarget < DISPLAYNAME_DISTANCE); + 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 = textRenderer(CHAT)->computeWidth(*it)); } glPushMatrix(); @@ -207,7 +244,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()); + textRenderer(CHAT)->draw(-width / 2.0f, 0, _chatMessage.c_str()); } else { // rather than using substr and allocating a new string, just replace the last @@ -215,10 +252,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()); + textRenderer(CHAT)->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); + textRenderer(CHAT)->draw(width / 2.0f - lastWidth, 0, _chatMessage.c_str() + lastIndex); } glEnable(GL_LIGHTING); glDepthMask(true); @@ -254,6 +291,93 @@ void Avatar::renderBody(bool forceRenderHead) { getHand()->render(false); } +void Avatar::renderDisplayName() { + + if (_displayName.isEmpty() || _displayNameAlpha == 0.0f) { + return; + } + + glDisable(GL_LIGHTING); + + glPushMatrix(); + glm::vec3 textPosition = getPosition() + getBodyUpDirection() * ((getSkeletonHeight() + getHeadHeight()) / 1.5f); + glTranslatef(textPosition.x, textPosition.y, textPosition.z); + + // we need "always facing camera": we must remove the camera rotation from the stack + glm::quat rotation = Application::getInstance()->getCamera()->getRotation(); + glm::vec3 axis = glm::axis(rotation); + glRotatef(glm::angle(rotation), axis.x, axis.y, axis.z); + + // We need to compute the scale factor such as the text remains with fixed size respect to window coordinates + // We project a unit vector and check the difference in screen coordinates, to check which is the + // correction scale needed + // save the matrices for later scale correction factor + glm::dmat4 modelViewMatrix; + glm::dmat4 projectionMatrix; + GLint viewportMatrix[4]; + Application::getInstance()->getModelViewMatrix(&modelViewMatrix); + Application::getInstance()->getProjectionMatrix(&projectionMatrix); + glGetIntegerv(GL_VIEWPORT, viewportMatrix); + GLdouble result0[3], result1[3]; + + glm::dvec3 upVector(modelViewMatrix[1]); + + glm::dvec3 testPoint0 = glm::dvec3(textPosition); + glm::dvec3 testPoint1 = glm::dvec3(textPosition) + upVector; + + bool success; + success = gluProject(testPoint0.x, testPoint0.y, testPoint0.z, + (GLdouble*)&modelViewMatrix, (GLdouble*)&projectionMatrix, viewportMatrix, + &result0[0], &result0[1], &result0[2]); + success = success && + gluProject(testPoint1.x, testPoint1.y, testPoint1.z, + (GLdouble*)&modelViewMatrix, (GLdouble*)&projectionMatrix, viewportMatrix, + &result1[0], &result1[1], &result1[2]); + + if (success) { + double textWindowHeight = abs(result1[1] - result0[1]); + float scaleFactor = (textWindowHeight > EPSILON) ? 1.0f / textWindowHeight : 1.0f; + glScalef(scaleFactor, scaleFactor, 1.0); + + // draw a gray background + QFontMetrics metrics = textRenderer(DISPLAYNAME)->metrics(); + int bottom = -metrics.descent(), top = bottom + metrics.height(); + int left = -_displayNameWidth/2, right = _displayNameWidth/2; + const int border = 5; + bottom -= border; + left -= border; + top += border; + right += border; + + // We are drawing coplanar textures with depth: need the polygon offset + glEnable(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(1.0f, 1.0f); + + glColor4f(0.2f, 0.2f, 0.2f, _displayNameAlpha); + glBegin(GL_QUADS); + glVertex2f(left, bottom); + glVertex2f(right, bottom); + glVertex2f(right, top); + glVertex2f(left, top); + glEnd(); + + glScalef(1.0f, -1.0f, 1.0f); // TextRenderer::draw paints the text upside down in y axis + glColor4f(0.93f, 0.93f, 0.93f, _displayNameAlpha); + + QByteArray ba = _displayName.toLocal8Bit(); + const char* text = ba.data(); + + glDisable(GL_POLYGON_OFFSET_FILL); + textRenderer(DISPLAYNAME)->draw(-_displayNameWidth / 2, 0, text); + + + } + + glPopMatrix(); + + glEnable(GL_LIGHTING); +} + bool Avatar::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance) const { float minDistance = FLT_MAX; float modelDistance; @@ -363,6 +487,15 @@ void Avatar::setSkeletonModelURL(const QUrl &skeletonModelURL) { _skeletonModel.setURL(_skeletonModelURL, DEFAULT_SKELETON_MODEL_URL); } +void Avatar::setDisplayName(const QString& displayName) { + AvatarData::setDisplayName(displayName); + int width = 0; + for (int i = 0; i < displayName.size(); i++) { + width += (textRenderer(DISPLAYNAME)->computeWidth(displayName[i].toLatin1())); + } + _displayNameWidth = width; +} + int Avatar::parseData(const QByteArray& packet) { // change in position implies movement glm::vec3 oldPosition = _position; @@ -448,11 +581,16 @@ void Avatar::setScale(float scale) { } } -float Avatar::getHeight() const { +float Avatar::getSkeletonHeight() const { Extents extents = _skeletonModel.getBindExtents(); return extents.maximum.y - extents.minimum.y; } +float Avatar::getHeadHeight() const { + Extents extents = getHead()->getFaceModel().getBindExtents(); + return extents.maximum.y - extents.minimum.y; +} + bool Avatar::collisionWouldMoveAvatar(CollisionInfo& collision) const { if (!collision._data || collision._type != MODEL_COLLISION) { return false; @@ -491,3 +629,21 @@ float Avatar::getPelvisToHeadLength() const { return glm::distance(_position, getHead()->getPosition()); } +void Avatar::setShowDisplayName(bool showDisplayName) { + // For myAvatar, the alpha update is not done (called in simulate for other avatars) + if (Application::getInstance()->getAvatar() == this) { + if (showDisplayName) { + _displayNameAlpha = DISPLAYNAME_ALPHA; + } else { + _displayNameAlpha = 0.0f; + } + } + + if (showDisplayName) { + _displayNameTargetAlpha = DISPLAYNAME_ALPHA; + } else { + _displayNameTargetAlpha = 0.0f; + } + +} + diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 9d854e4cf8..6fa0f203e9 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -113,18 +113,23 @@ public: virtual void setFaceModelURL(const QUrl& faceModelURL); virtual void setSkeletonModelURL(const QUrl& skeletonModelURL); + virtual void setDisplayName(const QString& displayName); + + void setShowDisplayName(bool showDisplayName); int parseData(const QByteArray& packet); static void renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2, float radius1, float radius2); + + /// \return true if we expect the avatar would move as a result of the collision bool collisionWouldMoveAvatar(CollisionInfo& collision) const; /// \param collision a data structure for storing info about collisions against Models void applyCollision(CollisionInfo& collision); - float getBoundingRadius() const { return 0.5f * getHeight(); } + float getBoundingRadius() const { return 0.5f * getSkeletonHeight(); } public slots: void updateCollisionFlags(); @@ -154,7 +159,8 @@ protected: glm::quat computeRotationFromBodyToWorldUp(float proportion = 1.0f) const; void setScale(float scale); - float getHeight() const; + float getSkeletonHeight() const; + float getHeadHeight() const; float getPelvisFloatingHeight() const; float getPelvisToHeadLength() const; @@ -163,6 +169,8 @@ private: bool _initialized; void renderBody(bool forceRenderHead); + + void renderDisplayName(); }; #endif diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 51cea9d085..4cc568cf18 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -5,6 +5,9 @@ // Created by Stephen Birarda on 1/23/2014. // Copyright (c) 2014 HighFidelity, Inc. All rights reserved. // +#include + +#include #include #include @@ -71,6 +74,8 @@ void AvatarManager::renderAvatars(bool forceRenderHead, bool selfAvatarOnly) { "Application::renderAvatars()"); bool renderLookAtVectors = Menu::getInstance()->isOptionChecked(MenuOption::LookAtVectors); + + if (!selfAvatarOnly) { foreach (const AvatarSharedPointer& avatarPointer, _avatarHash) { Avatar* avatar = static_cast(avatarPointer.data()); @@ -184,8 +189,9 @@ void AvatarManager::processAvatarIdentityPacket(const QByteArray &packet) { while (!identityStream.atEnd()) { QUrl faceMeshURL, skeletonURL; - identityStream >> nodeUUID >> faceMeshURL >> skeletonURL; - + QString displayName; + identityStream >> nodeUUID >> faceMeshURL >> skeletonURL >> displayName; + // mesh URL for a UUID, find avatar in our list AvatarSharedPointer matchingAvatar = _avatarHash.value(nodeUUID); if (matchingAvatar) { @@ -198,6 +204,10 @@ void AvatarManager::processAvatarIdentityPacket(const QByteArray &packet) { if (avatar->getSkeletonModelURL() != skeletonURL) { avatar->setSkeletonModelURL(skeletonURL); } + + if (avatar->getDisplayName() != displayName) { + avatar->setDisplayName(displayName); + } } } } diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 4e8aab600c..016159f415 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -198,7 +198,7 @@ void MyAvatar::simulate(float deltaTime) { if (_collisionFlags != 0) { Camera* myCamera = Application::getInstance()->getCamera(); - float radius = getHeight() * COLLISION_RADIUS_SCALE; + float radius = getSkeletonHeight() * COLLISION_RADIUS_SCALE; if (myCamera->getMode() == CAMERA_MODE_FIRST_PERSON && !OculusManager::isConnected()) { radius = myCamera->getAspectRatio() * (myCamera->getNearClip() / cos(myCamera->getFieldOfView() / 2.f)); radius *= COLLISION_RADIUS_SCALAR; @@ -610,6 +610,7 @@ void MyAvatar::saveData(QSettings* settings) { settings->setValue("faceModelURL", _faceModelURL); settings->setValue("skeletonModelURL", _skeletonModelURL); + settings->setValue("displayName", _displayName); settings->endGroup(); } @@ -637,6 +638,7 @@ void MyAvatar::loadData(QSettings* settings) { setFaceModelURL(settings->value("faceModelURL").toUrl()); setSkeletonModelURL(settings->value("skeletonModelURL").toUrl()); + setDisplayName(settings->value("displayName").toString()); settings->endGroup(); } @@ -689,7 +691,9 @@ void MyAvatar::updateLookAtTargetAvatar(glm::vec3 &eyePosition) { (avatar->getScale() / avatar->getHead()->getScale()) + avatar->getHead()->getScalePivot(); _lookAtTargetAvatar = avatarPointer; return; + } else { } + } _lookAtTargetAvatar.clear(); } @@ -854,7 +858,7 @@ void MyAvatar::updateCollisionWithEnvironment(float deltaTime, float radius) { float pelvisFloatingHeight = getPelvisFloatingHeight(); if (Application::getInstance()->getEnvironment()->findCapsulePenetration( _position - up * (pelvisFloatingHeight - radius), - _position + up * (getHeight() - pelvisFloatingHeight + radius), radius, penetration)) { + _position + up * (getSkeletonHeight() - pelvisFloatingHeight + radius), radius, penetration)) { _lastCollisionPosition = _position; updateCollisionSound(penetration, deltaTime, ENVIRONMENT_COLLISION_FREQUENCY); applyHardCollision(penetration, ENVIRONMENT_SURFACE_ELASTICITY, ENVIRONMENT_SURFACE_DAMPING); @@ -869,7 +873,7 @@ void MyAvatar::updateCollisionWithVoxels(float deltaTime, float radius) { float pelvisFloatingHeight = getPelvisFloatingHeight(); if (Application::getInstance()->getVoxels()->findCapsulePenetration( _position - glm::vec3(0.0f, pelvisFloatingHeight - radius, 0.0f), - _position + glm::vec3(0.0f, getHeight() - pelvisFloatingHeight + radius, 0.0f), radius, penetration)) { + _position + glm::vec3(0.0f, getSkeletonHeight() - pelvisFloatingHeight + radius, 0.0f), radius, penetration)) { _lastCollisionPosition = _position; updateCollisionSound(penetration, deltaTime, VOXEL_COLLISION_FREQUENCY); applyHardCollision(penetration, VOXEL_ELASTICITY, VOXEL_DAMPING); diff --git a/interface/src/avatar/Profile.h b/interface/src/avatar/Profile.h index c32d89cfea..c1f3f3c4de 100644 --- a/interface/src/avatar/Profile.h +++ b/interface/src/avatar/Profile.h @@ -27,7 +27,7 @@ public: QString getUserString() const; const QString& getUsername() const { return _username; } - + void setUUID(const QUuid& uuid) { _uuid = uuid; } const QUuid& getUUID() { return _uuid; } @@ -45,6 +45,8 @@ public: private: void setUsername(const QString& username); + + void setDisplayName(const QString& displaName); QString _username; QUuid _uuid; diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 3c89f45d23..8e9eb430e8 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -35,7 +35,10 @@ AvatarData::AvatarData() : _keyState(NO_KEY_DOWN), _isChatCirclingEnabled(false), _headData(NULL), - _handData(NULL) + _handData(NULL), + _displayNameWidth(0), + _displayNameTargetAlpha(0.0f), + _displayNameAlpha(0.0f) { } @@ -270,7 +273,8 @@ bool AvatarData::hasIdentityChangedAfterParsing(const QByteArray &packet) { QUuid avatarUUID; QUrl faceModelURL, skeletonModelURL; - packetStream >> avatarUUID >> faceModelURL >> skeletonModelURL; + QString displayName; + packetStream >> avatarUUID >> faceModelURL >> skeletonModelURL >> displayName; bool hasIdentityChanged = false; @@ -283,15 +287,20 @@ bool AvatarData::hasIdentityChangedAfterParsing(const QByteArray &packet) { setSkeletonModelURL(skeletonModelURL); hasIdentityChanged = true; } - + + if (displayName != _displayName) { + setDisplayName(displayName); + hasIdentityChanged = true; + } + return hasIdentityChanged; } QByteArray AvatarData::identityByteArray() { QByteArray identityData; QDataStream identityStream(&identityData, QIODevice::Append); - - identityStream << QUuid() << _faceModelURL << _skeletonModelURL; + + identityStream << QUuid() << _faceModelURL << _skeletonModelURL << _displayName; return identityData; } @@ -308,6 +317,13 @@ void AvatarData::setSkeletonModelURL(const QUrl& skeletonModelURL) { qDebug() << "Changing skeleton model for avatar to" << _skeletonModelURL.toString(); } +void AvatarData::setDisplayName(const QString& displayName) { + _displayName = displayName; + + qDebug() << "Changing display name for avatar to" << 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 7bd2bf57e7..a889b52bd0 100755 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -150,11 +150,13 @@ public: const QUrl& getFaceModelURL() const { return _faceModelURL; } const QUrl& getSkeletonModelURL() const { return _skeletonModelURL; } + const QString& getDisplayName() const { return _displayName; } virtual void setFaceModelURL(const QUrl& faceModelURL); virtual void setSkeletonModelURL(const QUrl& skeletonModelURL); - - virtual float getBoundingRadius() const { return 1.f; } + virtual void setDisplayName(const QString& displayName); + virtual float getBoundingRadius() const { return 1.f; } + protected: glm::vec3 _position; glm::vec3 _handPosition; @@ -183,6 +185,12 @@ protected: QUrl _faceModelURL; QUrl _skeletonModelURL; + QString _displayName; + + int _displayNameWidth; + float _displayNameTargetAlpha; + float _displayNameAlpha; + private: // privatize the copy constructor and assignment operator so they cannot be called AvatarData(const AvatarData&);