From c957dcceb50f4a6ae3995a826fc4f811f84c70bc Mon Sep 17 00:00:00 2001 From: Jose Carlos Date: Sat, 8 Feb 2014 02:21:00 +0100 Subject: [PATCH 01/26] ADDED the fields in interface-preferences for display name editting --- interface/src/Menu.cpp | 5 +++++ interface/src/avatar/Profile.cpp | 5 +++++ interface/src/avatar/Profile.h | 5 +++++ 3 files changed, 15 insertions(+) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 709f848a2f..6e48da0070 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -770,6 +770,11 @@ void Menu::editPreferences() { skeletonURLEdit->setMinimumWidth(QLINE_MINIMUM_WIDTH); form->addRow("Skeleton URL:", skeletonURLEdit); + QString displayNameString = applicationInstance->getProfile()->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); diff --git a/interface/src/avatar/Profile.cpp b/interface/src/avatar/Profile.cpp index 902a0ea12a..f0dcbec9c1 100644 --- a/interface/src/avatar/Profile.cpp +++ b/interface/src/avatar/Profile.cpp @@ -17,6 +17,7 @@ Profile::Profile(const QString &username) : _username(), + _displayName(), _uuid(), _lastDomain(), _lastPosition(0.0, 0.0, 0.0), @@ -211,3 +212,7 @@ void Profile::processDataServerResponse(const QString& userString, const QString void Profile::setUsername(const QString& username) { _username = username; } + +void Profile::setDisplayName(const QString& displayName) { + _displayName = displayName; +} diff --git a/interface/src/avatar/Profile.h b/interface/src/avatar/Profile.h index 5cb2295f5b..1709bbde04 100644 --- a/interface/src/avatar/Profile.h +++ b/interface/src/avatar/Profile.h @@ -27,6 +27,8 @@ public: QString getUserString() const; const QString& getUsername() const { return _username; } + + const QString& getDisplayName() const { return _displayName; } void setUUID(const QUuid& uuid); const QUuid& getUUID() { return _uuid; } @@ -51,8 +53,11 @@ public: private: void setUsername(const QString& username); + + void setDisplayName(const QString& displaName); QString _username; + QString _displayName; QUuid _uuid; QString _lastDomain; glm::vec3 _lastPosition; From d05fb392e0f8b74e78decfcdd347d13242f4d0a2 Mon Sep 17 00:00:00 2001 From: Jose Carlos Date: Sun, 9 Feb 2014 23:39:53 +0100 Subject: [PATCH 02/26] Always facing camera billboard TODO: having constant fix size --- interface/src/avatar/AvatarManager.cpp | 86 ++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index a4a85f5770..5bad11d4c5 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -8,6 +8,7 @@ #include #include +#include #include "Application.h" #include "Avatar.h" @@ -74,6 +75,91 @@ 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); + char 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(); + glTranslated(textPosition.x, textPosition.y, textPosition.z); + // Extract rotation matrix from the modelview matrix + glm::dmat4 modelViewMatrix; + + glGetDoublev(GL_MODELVIEW_MATRIX, (GLdouble*)&modelViewMatrix); + glm::dmat4 modelViewMatrix2(modelViewMatrix); + glm::dvec3 upVector(modelViewMatrix[1]); + + // 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]; + 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]); + std::cout << "diff x=" << result1[0] - result0[0] << " diff y="<< result1[1] - result0[1] << " diff z="<< result1[2] - result0[2] << std::endl; + float textPointSize = 12.0; + float scaleFactor = textPointSize / textWindowHeight; + + // glScalef(scaleFactor, scaleFactor, 1.0); + + glColor3f(0.0f, 1.0f, 0.0f); + + // TextRenderer, based on QT opengl text rendering functions + TextRenderer* renderer = new TextRenderer(SANS_FONT_FAMILY, 24, -1, false, TextRenderer::SHADOW_EFFECT); + renderer->draw(0,0, text); + delete renderer; + } + + glPopMatrix(); + + // ------------------------------------------------------------------------------------- + // josecpujol(end) + // ------------------------------------------------------------------------------------- + + + if (!selfAvatarOnly) { foreach (const AvatarSharedPointer& avatarPointer, _avatarHash) { Avatar* avatar = static_cast(avatarPointer.data()); From 4aa053befe3d4f2c81266f0c2a75c0c41c531414 Mon Sep 17 00:00:00 2001 From: Jose Carlos Date: Sun, 9 Feb 2014 23:59:51 +0100 Subject: [PATCH 03/26] Constant size in 3D world billboard text --- interface/src/avatar/AvatarManager.cpp | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 5bad11d4c5..985a642e56 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -97,13 +97,12 @@ void AvatarManager::renderAvatars(bool forceRenderHead, bool selfAvatarOnly) { 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); - glm::dmat4 modelViewMatrix2(modelViewMatrix); - glm::dvec3 upVector(modelViewMatrix[1]); // Delete rotation info modelViewMatrix[0][0] = modelViewMatrix[1][1] = modelViewMatrix[2][2] = 1.0; @@ -116,16 +115,17 @@ void AvatarManager::renderAvatars(bool forceRenderHead, bool selfAvatarOnly) { // 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; + glm::dvec3 testPoint1 = textPosition + upVector; bool success; success = gluProject(testPoint0.x, testPoint0.y, testPoint0.z, @@ -138,16 +138,15 @@ void AvatarManager::renderAvatars(bool forceRenderHead, bool selfAvatarOnly) { if (success) { double textWindowHeight = abs(result1[1] - result0[1]); - std::cout << "diff x=" << result1[0] - result0[0] << " diff y="<< result1[1] - result0[1] << " diff z="<< result1[2] - result0[2] << std::endl; - float textPointSize = 12.0; - float scaleFactor = textPointSize / textWindowHeight; + float textScale = 1.0; + float scaleFactor = textScale / textWindowHeight; - // glScalef(scaleFactor, scaleFactor, 1.0); + glScalef(scaleFactor, scaleFactor, 1.0); - glColor3f(0.0f, 1.0f, 0.0f); + glColor3f(1.0, 1.0, 0.0); // TextRenderer, based on QT opengl text rendering functions - TextRenderer* renderer = new TextRenderer(SANS_FONT_FAMILY, 24, -1, false, TextRenderer::SHADOW_EFFECT); + TextRenderer* renderer = new TextRenderer(SANS_FONT_FAMILY, 24, -1, false, TextRenderer::NO_EFFECT); renderer->draw(0,0, text); delete renderer; } From b42c2a9dbea8a0175fe03d58526089827b807989 Mon Sep 17 00:00:00 2001 From: Jose Carlos Date: Mon, 10 Feb 2014 23:55:43 +0100 Subject: [PATCH 04/26] Centered text --- interface/src/avatar/AvatarManager.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 985a642e56..71f963a211 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -5,7 +5,7 @@ // Created by Stephen Birarda on 1/23/2014. // Copyright (c) 2014 HighFidelity, Inc. All rights reserved. // - +#include #include #include #include @@ -79,7 +79,7 @@ void AvatarManager::renderAvatars(bool forceRenderHead, bool selfAvatarOnly) { // 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); - char text[] = "my string"; + std::string text("my string"); // Draw a fake avatar glPushMatrix(); @@ -143,12 +143,16 @@ void AvatarManager::renderAvatars(bool forceRenderHead, bool selfAvatarOnly) { glScalef(scaleFactor, scaleFactor, 1.0); - glColor3f(1.0, 1.0, 0.0); - + glColor3f(0.93, 0.93, 0.93); + // TextRenderer, based on QT opengl text rendering functions - TextRenderer* renderer = new TextRenderer(SANS_FONT_FAMILY, 24, -1, false, TextRenderer::NO_EFFECT); - renderer->draw(0,0, text); - delete renderer; + 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(); From 319d1f67959922a2cd47d6b9ef7779aedfca7913 Mon Sep 17 00:00:00 2001 From: Jose Carlos Date: Wed, 12 Feb 2014 00:54:50 +0100 Subject: [PATCH 05/26] 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&); From b899834c54a89437544fcc4a3bc0d8acf99448c9 Mon Sep 17 00:00:00 2001 From: Jose Carlos Date: Fri, 14 Feb 2014 00:23:21 +0100 Subject: [PATCH 06/26] Show "displayname" in correct position Show "displayname" when on mouse hover Persistant displayname data --- interface/src/Menu.cpp | 2 +- interface/src/avatar/Avatar.cpp | 28 +++++++++++++++++++--------- interface/src/avatar/Avatar.h | 6 ++++++ interface/src/avatar/MyAvatar.cpp | 7 +++++++ interface/src/avatar/Profile.cpp | 5 ----- interface/src/avatar/Profile.h | 3 --- libraries/avatars/src/AvatarData.cpp | 14 +++++++------- libraries/avatars/src/AvatarData.h | 6 +++--- 8 files changed, 43 insertions(+), 28 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 6dbbf176ee..394ca4febd 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -781,7 +781,7 @@ void Menu::editPreferences() { skeletonURLEdit->setMinimumWidth(QLINE_MINIMUM_WIDTH); form->addRow("Skeleton URL:", skeletonURLEdit); - QString displayNameString = applicationInstance->getProfile()->getDisplayName(); + QString displayNameString = applicationInstance->getAvatar()->getDisplayNameStr(); QLineEdit* displayNameEdit = new QLineEdit(displayNameString); displayNameEdit->setMinimumWidth(QLINE_MINIMUM_WIDTH); form->addRow("Display name:", displayNameEdit); diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index dc92d1eed9..29d9011bac 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -76,7 +76,8 @@ Avatar::Avatar() : _moving(false), _owningAvatarMixer(), _initialized(false), - _displayNameWidth(0) + _displayNameWidth(0), + _isShowDisplayName(false) { // we may have been created in the network thread, but we live in the main thread moveToThread(Application::getInstance()->thread()); @@ -187,7 +188,9 @@ void Avatar::render(bool forceRenderHead) { } // render display name - renderDisplayName(); + if (_isShowDisplayName) { + renderDisplayName(); + } if (!_chatMessage.empty()) { int width = 0; @@ -261,11 +264,14 @@ void Avatar::renderBody(bool forceRenderHead) { void Avatar::renderDisplayName() { - if (_displayNameStr.isEmpty()) { - return; + QString displayName; + if (_displayName.isEmpty()) { + displayName = "test string"; + } else { + displayName = _displayName; } - - glm::vec3 textPosition = _head.getPosition(); //+ glm::vec3(0,50,0); + + glm::vec3 textPosition = getPosition() + getBodyUpDirection() * getHeight(); // Scale is already considered in getHeight glPushMatrix(); glDepthMask(false); @@ -318,11 +324,11 @@ void Avatar::renderDisplayName() { glScalef(scaleFactor, scaleFactor, 1.0); - glColor3f(0.93, 0.93, 0.93); + glColor3f((GLfloat)0.93, (GLfloat)0.93, (GLfloat)0.93); // TextRenderer, based on QT opengl text rendering functions - QByteArray ba = _displayNameStr.toLocal8Bit(); + QByteArray ba = displayName.toLocal8Bit(); const char *text = ba.data(); displayNameTextRenderer()->draw(-_displayNameWidth/2.0, 0, text); } @@ -429,7 +435,7 @@ void Avatar::setSkeletonModelURL(const QUrl &skeletonModelURL) { } void Avatar::setDisplayName(const QString& displayName) { - AvatarData::setDisplayNameStr(displayName); + AvatarData::setDisplayName(displayName); int width = 0; for (int i = 0; i < displayName.size(); i++) { width += (displayNameTextRenderer()->computeWidth(displayName[i].toLatin1())); @@ -519,3 +525,7 @@ float Avatar::getPelvisToHeadLength() const { return glm::distance(_position, _head.getPosition()); } +void Avatar::setShowDisplayName(bool showDisplayName) { + _isShowDisplayName = showDisplayName; +} + diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 41b821838c..0ac5668555 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -116,6 +116,8 @@ 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); @@ -150,11 +152,15 @@ protected: float getPelvisFloatingHeight() const; float getPelvisToHeadLength() const; + + + private: bool _initialized; int _displayNameWidth; + bool _isShowDisplayName; diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 98eb9a4431..59055e259e 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -63,6 +63,7 @@ MyAvatar::MyAvatar() : for (int i = 0; i < MAX_DRIVE_KEYS; i++) { _driveKeys[i] = 0.0f; } + setShowDisplayName(true); } MyAvatar::~MyAvatar() { @@ -611,6 +612,7 @@ void MyAvatar::saveData(QSettings* settings) { settings->setValue("faceModelURL", _faceModelURL); settings->setValue("skeletonModelURL", _skeletonModelURL); + settings->setValue("displayName", _displayName); settings->endGroup(); } @@ -638,6 +640,7 @@ void MyAvatar::loadData(QSettings* settings) { setFaceModelURL(settings->value("faceModelURL").toUrl()); setSkeletonModelURL(settings->value("skeletonModelURL").toUrl()); + setDisplayName(settings->value("displayName").toString()); settings->endGroup(); } @@ -689,8 +692,12 @@ void MyAvatar::updateLookAtTargetAvatar(glm::vec3 &eyePosition) { eyePosition = (avatar->getHead().calculateAverageEyePosition() - avatar->getHead().getScalePivot()) * (avatar->getScale() / avatar->getHead().getScale()) + avatar->getHead().getScalePivot(); _lookAtTargetAvatar = avatarPointer; + avatar->setShowDisplayName(true); return; + } else { + avatar->setShowDisplayName(false); } + } _lookAtTargetAvatar.clear(); } diff --git a/interface/src/avatar/Profile.cpp b/interface/src/avatar/Profile.cpp index b910b56f76..a2a412199e 100644 --- a/interface/src/avatar/Profile.cpp +++ b/interface/src/avatar/Profile.cpp @@ -17,7 +17,6 @@ Profile::Profile(const QString &username) : _username(), - _displayName(), _uuid(), _lastDomain(), _lastPosition(0.0, 0.0, 0.0), @@ -166,7 +165,3 @@ void Profile::processDataServerResponse(const QString& userString, const QString void Profile::setUsername(const QString& username) { _username = username; } - -void Profile::setDisplayName(const QString& displayName) { - _displayName = displayName; -} diff --git a/interface/src/avatar/Profile.h b/interface/src/avatar/Profile.h index 41e6b671fb..c1f3f3c4de 100644 --- a/interface/src/avatar/Profile.h +++ b/interface/src/avatar/Profile.h @@ -28,8 +28,6 @@ public: const QString& getUsername() const { return _username; } - const QString& getDisplayName() const { return _displayName; } - void setUUID(const QUuid& uuid) { _uuid = uuid; } const QUuid& getUUID() { return _uuid; } @@ -51,7 +49,6 @@ private: void setDisplayName(const QString& displaName); QString _username; - QString _displayName; QUuid _uuid; QString _lastDomain; glm::vec3 _lastPosition; diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 3c711dc127..a16feb8514 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -274,8 +274,8 @@ bool AvatarData::hasIdentityChangedAfterParsing(const QByteArray &packet) { QUuid avatarUUID; QUrl faceModelURL, skeletonModelURL; - QString displayNameStr; - packetStream >> avatarUUID >> faceModelURL >> skeletonModelURL >> displayNameStr; + QString displayName; + packetStream >> avatarUUID >> faceModelURL >> skeletonModelURL >> displayName; bool hasIdentityChanged = false; @@ -289,8 +289,8 @@ bool AvatarData::hasIdentityChangedAfterParsing(const QByteArray &packet) { hasIdentityChanged = true; } - if (displayNameStr != _displayNameStr) { - setDisplayNameStr(displayNameStr); + if (displayName != _displayName) { + setDisplayName(displayName); hasIdentityChanged = true; } @@ -301,7 +301,7 @@ QByteArray AvatarData::identityByteArray() { QByteArray identityData; QDataStream identityStream(&identityData, QIODevice::Append); - identityStream << QUuid() << _faceModelURL << _skeletonModelURL << _displayNameStr; + identityStream << QUuid() << _faceModelURL << _skeletonModelURL << _displayName; return identityData; } @@ -316,9 +316,9 @@ void AvatarData::setSkeletonModelURL(const QUrl& skeletonModelURL) { _skeletonModelURL = skeletonModelURL; } -void AvatarData::setDisplayNameStr(const QString& displayName) { +void AvatarData::setDisplayName(const QString& displayName) { qDebug() << "Changing display name for avatar to" << displayName; - _displayNameStr = displayName; + _displayName = displayName; } diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 4fc4e1f4f7..289fd2b21c 100755 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -149,10 +149,10 @@ public: const QUrl& getFaceModelURL() const { return _faceModelURL; } const QUrl& getSkeletonModelURL() const { return _skeletonModelURL; } - const QString& getDisplayNameStr() const { return _displayNameStr; } + const QString& getDisplayNameStr() const { return _displayName; } virtual void setFaceModelURL(const QUrl& faceModelURL); virtual void setSkeletonModelURL(const QUrl& skeletonModelURL); - virtual void setDisplayNameStr(const QString& displayName); + virtual void setDisplayName(const QString& displayName); protected: glm::vec3 _position; @@ -182,7 +182,7 @@ protected: QUrl _faceModelURL; QUrl _skeletonModelURL; - QString _displayNameStr; + QString _displayName; private: // privatize the copy constructor and assignment operator so they cannot be called AvatarData(const AvatarData&); From 19cb20f0cd1301449c36c54428c5cf7999472cb2 Mon Sep 17 00:00:00 2001 From: Jose Carlos Date: Sat, 15 Feb 2014 01:05:21 +0100 Subject: [PATCH 07/26] Added rect around the display name with proper size, paying attention to QFontMetrics data Fully wired up the message sending and receiving from server --- interface/src/Menu.cpp | 2 +- interface/src/avatar/Avatar.cpp | 39 +++++++++++++++++++------- interface/src/avatar/AvatarManager.cpp | 9 ++++-- libraries/avatars/src/AvatarData.cpp | 5 ++-- libraries/avatars/src/AvatarData.h | 2 +- 5 files changed, 41 insertions(+), 16 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 86ab8d0714..bf98738097 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -782,7 +782,7 @@ void Menu::editPreferences() { skeletonURLEdit->setPlaceholderText(DEFAULT_BODY_MODEL_URL.toString()); form->addRow("Skeleton URL:", skeletonURLEdit); - QString displayNameString = applicationInstance->getAvatar()->getDisplayNameStr(); + QString displayNameString = applicationInstance->getAvatar()->getDisplayName(); QLineEdit* displayNameEdit = new QLineEdit(displayNameString); displayNameEdit->setMinimumWidth(QLINE_MINIMUM_WIDTH); form->addRow("Display name:", displayNameEdit); diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 4c071adf15..837c77b970 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -270,7 +270,7 @@ void Avatar::renderDisplayName() { QString displayName; if (_displayName.isEmpty()) { - displayName = "test string"; + displayName = "test string"; // just for debugging } else { displayName = _displayName; } @@ -278,7 +278,12 @@ void Avatar::renderDisplayName() { glm::vec3 textPosition = getPosition() + getBodyUpDirection() * getHeight(); // Scale is already considered in getHeight glPushMatrix(); glDepthMask(false); + glDisable(GL_LIGHTING); + // Set the correct modelview matrix: set the identity matrix in the rotation part + // [R|t1] = current modelview matrix (the camera rotation and translation) + // [I|t2] = the translation for the text + // We want this final model view matrix: [I | t1 + R*t2] glm::dmat4 modelViewMatrix2; glGetDoublev(GL_MODELVIEW_MATRIX, (GLdouble*)&modelViewMatrix2); glTranslatef(textPosition.x, textPosition.y, textPosition.z); @@ -293,7 +298,7 @@ void Avatar::renderDisplayName() { 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 @@ -320,22 +325,36 @@ void Avatar::renderDisplayName() { if (success) { double textWindowHeight = abs(result1[1] - result0[1]); - float textScale = 1.0; - float scaleFactor = 1.0; - if (textWindowHeight > EPSILON) { - scaleFactor = textScale / textWindowHeight; - } + float scaleFactor = (textWindowHeight > EPSILON) ? 1.0f / textWindowHeight : 1.0f; + glScalef(scaleFactor, scaleFactor, 1.0); - glScalef(scaleFactor, scaleFactor, 1.0); + // draw a gray background so that we can actually see what we're typing + QFontMetrics metrics = displayNameTextRenderer()->metrics(); + int bottom = -metrics.descent(), top = bottom + metrics.height(); + int left = -_displayNameWidth/2, right = _displayNameWidth/2; + int border = 5; + bottom -= border; + left -= border; + top += border; + right += border; - glColor3f((GLfloat)0.93, (GLfloat)0.93, (GLfloat)0.93); + glColor3f(0.2f, 0.2f, 0.2f); + glBegin(GL_QUADS); + glVertex2f(left, bottom); + glVertex2f(right, bottom); + glVertex2f(right, top); + glVertex2f(left, top); + glEnd(); - // TextRenderer, based on QT opengl text rendering functions + glScalef(1.0f, -1.0f, 1.0f); // TextRenderer::draw paints the text upside down in y axis + glColor3f(0.93f, 0.93f, 0.93f); + QByteArray ba = displayName.toLocal8Bit(); const char *text = ba.data(); displayNameTextRenderer()->draw(-_displayNameWidth/2.0, 0, text); } + glEnable(GL_LIGHTING); glDepthMask(true); glPopMatrix(); } diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 551734666f..026a5d6291 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -187,8 +187,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) { @@ -201,6 +202,10 @@ void AvatarManager::processAvatarIdentityPacket(const QByteArray &packet) { if (avatar->getSkeletonModelURL() != skeletonURL) { avatar->setSkeletonModelURL(skeletonURL); } + + if (avatar->getDisplayName() != displayName) { + avatar->setDisplayName(displayName); + } } } } diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 3cb5a6f0b1..548129b871 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -300,7 +300,7 @@ bool AvatarData::hasIdentityChangedAfterParsing(const QByteArray &packet) { QByteArray AvatarData::identityByteArray() { QByteArray identityData; QDataStream identityStream(&identityData, QIODevice::Append); - + identityStream << QUuid() << _faceModelURL << _skeletonModelURL << _displayName; return identityData; @@ -319,8 +319,9 @@ void AvatarData::setSkeletonModelURL(const QUrl& skeletonModelURL) { } void AvatarData::setDisplayName(const QString& displayName) { - qDebug() << "Changing display name for avatar to" << displayName; _displayName = displayName; + + qDebug() << "Changing display name for avatar to" << displayName; } diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 01cfa6dd58..f5d9da2447 100755 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -148,7 +148,7 @@ public: const QUrl& getFaceModelURL() const { return _faceModelURL; } const QUrl& getSkeletonModelURL() const { return _skeletonModelURL; } - const QString& getDisplayNameStr() const { return _displayName; } + const QString& getDisplayName() const { return _displayName; } virtual void setFaceModelURL(const QUrl& faceModelURL); virtual void setSkeletonModelURL(const QUrl& skeletonModelURL); virtual void setDisplayName(const QString& displayName); From af48998cc783ddf60d6ee3e8eeed53923abd9e02 Mon Sep 17 00:00:00 2001 From: Jose Carlos Date: Sat, 15 Feb 2014 18:40:36 +0100 Subject: [PATCH 08/26] Fixed position of display name: we take into account skeleton and head's height Saved opengl state in renderDisplayName Moved display data to AvatarData Unified static chat function for chat and display name --- interface/src/avatar/Avatar.cpp | 99 +++++++++++++++------------- interface/src/avatar/Avatar.h | 9 +-- interface/src/avatar/MyAvatar.cpp | 10 +-- libraries/avatars/src/AvatarData.cpp | 4 +- libraries/avatars/src/AvatarData.h | 4 ++ 5 files changed, 70 insertions(+), 56 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 837c77b970..21aee11936 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -75,9 +75,7 @@ Avatar::Avatar() : _moving(false), _owningAvatarMixer(), _collisionFlags(0), - _initialized(false), - _displayNameWidth(0), - _isShowDisplayName(false) + _initialized(false) { // we may have been created in the network thread, but we live in the main thread moveToThread(Application::getInstance()->thread()); @@ -148,14 +146,23 @@ void Avatar::setMouseRay(const glm::vec3 &origin, const glm::vec3 &direction) { _mouseRayDirection = direction; } -static TextRenderer* chatTextRenderer() { - static TextRenderer* renderer = new TextRenderer(SANS_FONT_FAMILY, 24, -1, false, TextRenderer::SHADOW_EFFECT); - return renderer; -} +enum TextRendererType { + CHAT, + DISPLAYNAME +}; -static TextRenderer* displayNameTextRenderer() { - static TextRenderer* renderer = new TextRenderer(SANS_FONT_FAMILY, 12, -1, false, TextRenderer::SHADOW_EFFECT); - return renderer; +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) { @@ -177,7 +184,7 @@ void Avatar::render(bool forceRenderHead) { // render sphere when far away const float MAX_ANGLE = 10.f; - float height = getHeight(); + float height = getSkeletonHeight(); glm::vec3 delta = height * (_head.getCameraOrientation() * IDENTITY_UP) / 2.f; float angle = abs(angleBetween(toTarget + delta, toTarget - delta)); @@ -200,7 +207,7 @@ void Avatar::render(bool forceRenderHead) { int width = 0; int lastWidth = 0; for (string::iterator it = _chatMessage.begin(); it != _chatMessage.end(); it++) { - width += (lastWidth = chatTextRenderer()->computeWidth(*it)); + width += (lastWidth = textRenderer(CHAT)->computeWidth(*it)); } glPushMatrix(); @@ -219,7 +226,7 @@ void Avatar::render(bool forceRenderHead) { glDisable(GL_LIGHTING); glDepthMask(false); if (_keyState == NO_KEY_DOWN) { - chatTextRenderer()->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 @@ -227,10 +234,10 @@ void Avatar::render(bool forceRenderHead) { int lastIndex = _chatMessage.size() - 1; char lastChar = _chatMessage[lastIndex]; _chatMessage[lastIndex] = '\0'; - chatTextRenderer()->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); - chatTextRenderer()->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); @@ -267,38 +274,32 @@ void Avatar::renderBody(bool forceRenderHead) { } void Avatar::renderDisplayName() { - QString displayName; if (_displayName.isEmpty()) { displayName = "test string"; // just for debugging } else { displayName = _displayName; } - - glm::vec3 textPosition = getPosition() + getBodyUpDirection() * getHeight(); // Scale is already considered in getHeight + + glm::vec3 textPosition = getPosition() + getBodyUpDirection() * (getSkeletonHeight() + getHeadHeight()); glPushMatrix(); + + // save opengl state + GLboolean isDepthMaskEnabled; + glGetBooleanv(GL_DEPTH_WRITEMASK, &isDepthMaskEnabled); + GLboolean isLightingEnabled = glIsEnabled(GL_LIGHTING); + glDepthMask(false); glDisable(GL_LIGHTING); - - // Set the correct modelview matrix: set the identity matrix in the rotation part - // [R|t1] = current modelview matrix (the camera rotation and translation) - // [I|t2] = the translation for the text - // We want this final model view matrix: [I | t1 + R*t2] + 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 - + // 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 y = 0 and y = 1 and check the difference in projection coordinates @@ -328,8 +329,8 @@ void Avatar::renderDisplayName() { float scaleFactor = (textWindowHeight > EPSILON) ? 1.0f / textWindowHeight : 1.0f; glScalef(scaleFactor, scaleFactor, 1.0); - // draw a gray background so that we can actually see what we're typing - QFontMetrics metrics = displayNameTextRenderer()->metrics(); + // draw a gray background + QFontMetrics metrics = textRenderer(DISPLAYNAME)->metrics(); int bottom = -metrics.descent(), top = bottom + metrics.height(); int left = -_displayNameWidth/2, right = _displayNameWidth/2; int border = 5; @@ -338,7 +339,7 @@ void Avatar::renderDisplayName() { top += border; right += border; - glColor3f(0.2f, 0.2f, 0.2f); + glColor4f(0.2f, 0.2f, 0.2f, 0.95f); glBegin(GL_QUADS); glVertex2f(left, bottom); glVertex2f(right, bottom); @@ -346,16 +347,21 @@ void Avatar::renderDisplayName() { glVertex2f(left, top); glEnd(); - glScalef(1.0f, -1.0f, 1.0f); // TextRenderer::draw paints the text upside down in y axis - glColor3f(0.93f, 0.93f, 0.93f); + glColor4f(0.93f, 0.93f, 0.93f, 0.95f); QByteArray ba = displayName.toLocal8Bit(); const char *text = ba.data(); - displayNameTextRenderer()->draw(-_displayNameWidth/2.0, 0, text); + textRenderer(DISPLAYNAME)->draw(-_displayNameWidth/2.0, 0, text); + } + + // restore state + if (isLightingEnabled) { + glEnable(GL_LIGHTING); + } + if (isDepthMaskEnabled) { + glDepthMask(true); } - glEnable(GL_LIGHTING); - glDepthMask(true); glPopMatrix(); } @@ -466,7 +472,7 @@ void Avatar::setDisplayName(const QString& displayName) { AvatarData::setDisplayName(displayName); int width = 0; for (int i = 0; i < displayName.size(); i++) { - width += (displayNameTextRenderer()->computeWidth(displayName[i].toLatin1())); + width += (textRenderer(DISPLAYNAME)->computeWidth(displayName[i].toLatin1())); } _displayNameWidth = width; } @@ -556,11 +562,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 = _head.getFaceModel().getBindExtents(); + return extents.maximum.y - extents.minimum.y; +} + bool Avatar::collisionWouldMoveAvatar(ModelCollisionInfo& collision) const { // ATM only the Skeleton is pokeable // TODO: make poke affect head diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 19e720f771..5c19b8b60f 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -130,7 +130,9 @@ public: static void renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2, float radius1, float radius2); - float getHeight() const; + float getSkeletonHeight() const; + + float getHeadHeight() const; /// \return true if we expect the avatar would move as a result of the collision bool collisionWouldMoveAvatar(ModelCollisionInfo& collision) const; @@ -178,11 +180,6 @@ private: bool _initialized; - int _displayNameWidth; - bool _isShowDisplayName; - - - void renderBody(bool forceRenderHead); void renderDisplayName(); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index c97cc96ea8..72ab283da8 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -197,7 +197,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; @@ -840,7 +840,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); @@ -855,7 +855,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); @@ -962,7 +962,7 @@ void MyAvatar::updateCollisionWithAvatars(float deltaTime) { // no need to compute a bunch of stuff if we have one or fewer avatars return; } - float myBoundingRadius = 0.5f * getHeight(); + float myBoundingRadius = 0.5f * getSkeletonHeight(); // HACK: body-body collision uses two coaxial capsules with axes parallel to y-axis // TODO: make the collision work without assuming avatar orientation @@ -982,7 +982,7 @@ void MyAvatar::updateCollisionWithAvatars(float deltaTime) { if (_distanceToNearestAvatar > distance) { _distanceToNearestAvatar = distance; } - float theirBoundingRadius = 0.5f * avatar->getHeight(); + float theirBoundingRadius = 0.5f * avatar->getSkeletonHeight(); if (distance < myBoundingRadius + theirBoundingRadius) { Extents theirStaticExtents = _skeletonModel.getStaticExtents(); glm::vec3 staticScale = theirStaticExtents.maximum - theirStaticExtents.minimum; diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 548129b871..5a71f7c3d2 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -35,7 +35,9 @@ AvatarData::AvatarData() : _keyState(NO_KEY_DOWN), _isChatCirclingEnabled(false), _headData(NULL), - _handData(NULL) + _handData(NULL), + _displayNameWidth(0), + _isShowDisplayName(false) { } diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index f5d9da2447..6b3de797bb 100755 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -182,6 +182,10 @@ protected: QUrl _faceModelURL; QUrl _skeletonModelURL; QString _displayName; + + int _displayNameWidth; + bool _isShowDisplayName; + private: // privatize the copy constructor and assignment operator so they cannot be called AvatarData(const AvatarData&); From a8f1f9a00ae1342e81e1d0a3d2f47484fb8818b1 Mon Sep 17 00:00:00 2001 From: Jose Carlos Date: Sun, 16 Feb 2014 14:25:41 +0100 Subject: [PATCH 09/26] Added animation for fade out --- interface/src/avatar/Avatar.cpp | 79 ++++++++++++++++------------ interface/src/avatar/MyAvatar.cpp | 1 - libraries/avatars/src/AvatarData.cpp | 3 +- libraries/avatars/src/AvatarData.h | 1 + 4 files changed, 49 insertions(+), 35 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 21aee11936..681876550b 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -56,6 +56,8 @@ 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_FADEOUT_TIME = 0.5f; +const float DISPLAYNAME_ALPHA = 0.95f; Avatar::Avatar() : AvatarData(), @@ -111,7 +113,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(); @@ -138,7 +140,15 @@ 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 fadeout + if (!_isShowDisplayName && _displayNameAlpha > 0.0) { + // the alpha function is alpha = coef ^ time(zero based) + // We can make this function recursive: alpha(t) = alpha(t-dt) * coef^(dt) + float coef = pow(0.01f, 1.0f / DISPLAYNAME_FADEOUT_TIME); + _displayNameAlpha *= pow(coef, deltaTime); + _displayNameAlpha = _displayNameAlpha > 0.01? _displayNameAlpha : 0.0f; // The function is asymptotic to zero. 0.01 is 0 to us + } } void Avatar::setMouseRay(const glm::vec3 &origin, const glm::vec3 &direction) { @@ -199,9 +209,8 @@ void Avatar::render(bool forceRenderHead) { } // render display name - if (_isShowDisplayName) { - renderDisplayName(); - } + renderDisplayName(); + if (!_chatMessage.empty()) { int width = 0; @@ -274,16 +283,11 @@ void Avatar::renderBody(bool forceRenderHead) { } void Avatar::renderDisplayName() { - QString displayName; - if (_displayName.isEmpty()) { - displayName = "test string"; // just for debugging - } else { - displayName = _displayName; - } - - glm::vec3 textPosition = getPosition() + getBodyUpDirection() * (getSkeletonHeight() + getHeadHeight()); - glPushMatrix(); + if (_displayName.isEmpty() || _displayNameAlpha == 0.0f) { + return; + } + // save opengl state GLboolean isDepthMaskEnabled; glGetBooleanv(GL_DEPTH_WRITEMASK, &isDepthMaskEnabled); @@ -291,9 +295,17 @@ void Avatar::renderDisplayName() { glDepthMask(false); glDisable(GL_LIGHTING); - - glm::dmat4 modelViewMatrix2; - glGetDoublev(GL_MODELVIEW_MATRIX, (GLdouble*)&modelViewMatrix2); + + // save the matrices for later scale correction factor + glm::dmat4 modelViewMatrix; + GLdouble projectionMatrix[16]; + GLint viewportMatrix[4]; + glGetDoublev(GL_MODELVIEW_MATRIX, (GLdouble*)&modelViewMatrix); + glGetDoublev(GL_PROJECTION_MATRIX, (GLdouble*)&projectionMatrix); + glGetIntegerv(GL_VIEWPORT, viewportMatrix); + + glPushMatrix(); + glm::vec3 textPosition = getPosition() + getBodyUpDirection() * (getSkeletonHeight() + getHeadHeight()); glTranslatef(textPosition.x, textPosition.y, textPosition.z); // we need "always facing camera": we must remove the camera rotation from the stack @@ -302,26 +314,22 @@ void Avatar::renderDisplayName() { 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 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); + // We project a unit vector and check the difference in screen coordinates, to check which is the + // correction scale needed + 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*)&modelViewMatrix2, projectionMatrix, viewportMatrix, + (GLdouble*)&modelViewMatrix, projectionMatrix, viewportMatrix, &result0[0], &result0[1], &result0[2]); success = success && gluProject(testPoint1.x, testPoint1.y, testPoint1.z, - (GLdouble*)&modelViewMatrix2, projectionMatrix, viewportMatrix, + (GLdouble*)&modelViewMatrix, projectionMatrix, viewportMatrix, &result1[0], &result1[1], &result1[2]); if (success) { @@ -339,7 +347,7 @@ void Avatar::renderDisplayName() { top += border; right += border; - glColor4f(0.2f, 0.2f, 0.2f, 0.95f); + glColor4f(0.2f, 0.2f, 0.2f, _displayNameAlpha); glBegin(GL_QUADS); glVertex2f(left, bottom); glVertex2f(right, bottom); @@ -348,21 +356,23 @@ void Avatar::renderDisplayName() { 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, 0.95f); + glColor4f(0.93f, 0.93f, 0.93f, _displayNameAlpha); - QByteArray ba = displayName.toLocal8Bit(); + QByteArray ba = _displayName.toLocal8Bit(); const char *text = ba.data(); textRenderer(DISPLAYNAME)->draw(-_displayNameWidth/2.0, 0, text); } - // restore state + glPopMatrix(); + + // restore opengl state if (isLightingEnabled) { glEnable(GL_LIGHTING); } if (isDepthMaskEnabled) { glDepthMask(true); } - glPopMatrix(); + } bool Avatar::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance) const { @@ -612,5 +622,8 @@ float Avatar::getPelvisToHeadLength() const { void Avatar::setShowDisplayName(bool showDisplayName) { _isShowDisplayName = showDisplayName; + if (showDisplayName) { + _displayNameAlpha = DISPLAYNAME_ALPHA; + } } diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 72ab283da8..266051e22d 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -63,7 +63,6 @@ MyAvatar::MyAvatar() : for (int i = 0; i < MAX_DRIVE_KEYS; i++) { _driveKeys[i] = 0.0f; } - setShowDisplayName(true); } MyAvatar::~MyAvatar() { diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 5a71f7c3d2..106ac38702 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -37,7 +37,8 @@ AvatarData::AvatarData() : _headData(NULL), _handData(NULL), _displayNameWidth(0), - _isShowDisplayName(false) + _isShowDisplayName(false), + _displayNameAlpha(0.0f) { } diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 6b3de797bb..fe5a890614 100755 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -185,6 +185,7 @@ protected: int _displayNameWidth; bool _isShowDisplayName; + float _displayNameAlpha; private: // privatize the copy constructor and assignment operator so they cannot be called From 73e0c0ccf52b44cdef39b38151c3fbd796884ab1 Mon Sep 17 00:00:00 2001 From: Jose Carlos Date: Sun, 16 Feb 2014 21:33:46 +0100 Subject: [PATCH 10/26] Moving pow evaluation to const --- interface/src/avatar/Avatar.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 681876550b..7028e30a7e 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -57,6 +57,7 @@ const int NUM_BODY_CONE_SIDES = 9; const float CHAT_MESSAGE_SCALE = 0.0015f; const float CHAT_MESSAGE_HEIGHT = 0.1f; const float DISPLAYNAME_FADEOUT_TIME = 0.5f; +const float DISPLAYNAME_FADEOUT_FACTOR = pow(0.01f, 1.0f / DISPLAYNAME_FADEOUT_TIME); const float DISPLAYNAME_ALPHA = 0.95f; Avatar::Avatar() : @@ -145,8 +146,7 @@ void Avatar::simulate(float deltaTime) { if (!_isShowDisplayName && _displayNameAlpha > 0.0) { // the alpha function is alpha = coef ^ time(zero based) // We can make this function recursive: alpha(t) = alpha(t-dt) * coef^(dt) - float coef = pow(0.01f, 1.0f / DISPLAYNAME_FADEOUT_TIME); - _displayNameAlpha *= pow(coef, deltaTime); + _displayNameAlpha *= pow(DISPLAYNAME_FADEOUT_FACTOR, deltaTime); _displayNameAlpha = _displayNameAlpha > 0.01? _displayNameAlpha : 0.0f; // The function is asymptotic to zero. 0.01 is 0 to us } } From 96a160bade8b46a99f9dbd5deb8d90f6b26ea10b Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 17 Feb 2014 12:35:42 -0800 Subject: [PATCH 11/26] Moved some code in ImportDialog.cpp for consistency --- interface/src/ImportDialog.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/interface/src/ImportDialog.cpp b/interface/src/ImportDialog.cpp index ac7853629c..c276a4da6b 100644 --- a/interface/src/ImportDialog.cpp +++ b/interface/src/ImportDialog.cpp @@ -104,19 +104,6 @@ ImportDialog::ImportDialog(QWidget* parent) : setFileMode(QFileDialog::ExistingFile); setViewMode(QFileDialog::Detail); -#ifdef Q_OS_MAC - QString cmdString = ("Command"); -#else - QString cmdString = ("Control"); -#endif - QLabel* infoLabel = new QLabel(QString(INFO_LABEL_TEXT).arg(cmdString)); - infoLabel->setObjectName("infoLabel"); - - QGridLayout* gridLayout = (QGridLayout*) layout(); - gridLayout->addWidget(infoLabel, 2, 0, 2, 1); - gridLayout->addWidget(&_cancelButton, 2, 1, 2, 1); - gridLayout->addWidget(&_importButton, 2, 2, 2, 1); - setImportTypes(); setLayout(); @@ -175,6 +162,19 @@ void ImportDialog::saveCurrentFile(QString filename) { } void ImportDialog::setLayout() { + +#ifdef Q_OS_MAC + QString cmdString = ("Command"); +#else + QString cmdString = ("Control"); +#endif + QLabel* infoLabel = new QLabel(QString(INFO_LABEL_TEXT).arg(cmdString)); + infoLabel->setObjectName("infoLabel"); + + QGridLayout* gridLayout = (QGridLayout*) layout(); + gridLayout->addWidget(infoLabel, 2, 0, 2, 1); + gridLayout->addWidget(&_cancelButton, 2, 1, 2, 1); + gridLayout->addWidget(&_importButton, 2, 2, 2, 1); // set ObjectName used in qss for styling _importButton.setObjectName("importButton"); From 0ec554ec82ae1804fcbbd5a6124a5341b4bd5ff5 Mon Sep 17 00:00:00 2001 From: Jose Carlos Date: Tue, 18 Feb 2014 00:49:26 +0100 Subject: [PATCH 12/26] Added fadein and fadeout animations for display name --- interface/src/avatar/Avatar.cpp | 30 ++++++++++++++++++---------- interface/src/avatar/Avatar.h | 2 +- libraries/avatars/src/AvatarData.cpp | 2 +- libraries/avatars/src/AvatarData.h | 2 +- 4 files changed, 23 insertions(+), 13 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 86ffb2e5d4..55afe1905c 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -56,8 +56,8 @@ 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_FADEOUT_TIME = 0.5f; -const float DISPLAYNAME_FADEOUT_FACTOR = pow(0.01f, 1.0f / DISPLAYNAME_FADEOUT_TIME); +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() : @@ -142,12 +142,21 @@ 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 fadeout - if (!_isShowDisplayName && _displayNameAlpha > 0.0) { - // the alpha function is alpha = coef ^ time(zero based) - // We can make this function recursive: alpha(t) = alpha(t-dt) * coef^(dt) - _displayNameAlpha *= pow(DISPLAYNAME_FADEOUT_FACTOR, deltaTime); - _displayNameAlpha = _displayNameAlpha > 0.01? _displayNameAlpha : 0.0f; // The function is asymptotic to zero. 0.01 is 0 to us + // 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; } } @@ -628,9 +637,10 @@ float Avatar::getPelvisToHeadLength() const { } void Avatar::setShowDisplayName(bool showDisplayName) { - _isShowDisplayName = showDisplayName; if (showDisplayName) { - _displayNameAlpha = DISPLAYNAME_ALPHA; + _displayNameTargetAlpha = DISPLAYNAME_ALPHA; + } else { + _displayNameTargetAlpha = 0.0f; } } diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 7a9df0cdbb..c7b52301e3 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -128,7 +128,7 @@ public: /// \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(); diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 106ac38702..a49bd83df6 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -37,7 +37,7 @@ AvatarData::AvatarData() : _headData(NULL), _handData(NULL), _displayNameWidth(0), - _isShowDisplayName(false), + _displayNameTargetAlpha(0.0f), _displayNameAlpha(0.0f) { diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 48892647f5..6850af80a2 100755 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -182,7 +182,7 @@ protected: QString _displayName; int _displayNameWidth; - bool _isShowDisplayName; + float _displayNameTargetAlpha; float _displayNameAlpha; private: From 46ed5061961470deaad523fa000306343871709a Mon Sep 17 00:00:00 2001 From: Jose Carlos Date: Wed, 19 Feb 2014 00:04:00 +0100 Subject: [PATCH 13/26] Display names are shown when distance is below a threshold Used polygon offset to render display names Saved model view and projection matrices in order to save glGetDoublev calls --- interface/src/Application.cpp | 12 +++++++ interface/src/Application.h | 4 +++ interface/src/avatar/Avatar.cpp | 55 ++++++++++++++----------------- interface/src/avatar/MyAvatar.cpp | 2 -- 4 files changed, 41 insertions(+), 32 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 36fd8f9635..8f591d47ed 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -647,6 +647,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); } @@ -2894,6 +2897,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 a9c20ac00d..016fe0cbe8 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -188,6 +188,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; @@ -391,6 +394,7 @@ private: glm::mat4 _untranslatedViewMatrix; glm::vec3 _viewMatrixTranslation; + glm::mat4 _projectionMatrix; glm::mat4 _shadowMatrix; diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 55afe1905c..2b7cc94c86 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -185,12 +185,14 @@ static TextRenderer* textRenderer(TextRendererType type) { } 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); + Glower glower(_moving && lengthToTarget > GLOW_DISTANCE ? 1.0f : 0.0f); // render body if (Menu::getInstance()->isOptionChecked(MenuOption::CollisionProxies)) { @@ -217,11 +219,10 @@ void Avatar::render(bool forceRenderHead) { glPopMatrix(); } } - - // render display name + const float DISPLAYNAME_DISTANCE = 4.0f; + setShowDisplayName(lengthToTarget < DISPLAYNAME_DISTANCE); renderDisplayName(); - if (!_chatMessage.empty()) { int width = 0; int lastWidth = 0; @@ -298,22 +299,8 @@ void Avatar::renderDisplayName() { return; } - // save opengl state - GLboolean isDepthMaskEnabled; - glGetBooleanv(GL_DEPTH_WRITEMASK, &isDepthMaskEnabled); - GLboolean isLightingEnabled = glIsEnabled(GL_LIGHTING); - - glDepthMask(false); glDisable(GL_LIGHTING); - // save the matrices for later scale correction factor - glm::dmat4 modelViewMatrix; - GLdouble projectionMatrix[16]; - GLint viewportMatrix[4]; - glGetDoublev(GL_MODELVIEW_MATRIX, (GLdouble*)&modelViewMatrix); - glGetDoublev(GL_PROJECTION_MATRIX, (GLdouble*)&projectionMatrix); - glGetIntegerv(GL_VIEWPORT, viewportMatrix); - glPushMatrix(); glm::vec3 textPosition = getPosition() + getBodyUpDirection() * (getSkeletonHeight() + getHeadHeight()); glTranslatef(textPosition.x, textPosition.y, textPosition.z); @@ -326,6 +313,13 @@ void Avatar::renderDisplayName() { // 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]); @@ -335,11 +329,11 @@ void Avatar::renderDisplayName() { bool success; success = gluProject(testPoint0.x, testPoint0.y, testPoint0.z, - (GLdouble*)&modelViewMatrix, projectionMatrix, viewportMatrix, + (GLdouble*)&modelViewMatrix, (GLdouble*)&projectionMatrix, viewportMatrix, &result0[0], &result0[1], &result0[2]); success = success && gluProject(testPoint1.x, testPoint1.y, testPoint1.z, - (GLdouble*)&modelViewMatrix, projectionMatrix, viewportMatrix, + (GLdouble*)&modelViewMatrix, (GLdouble*)&projectionMatrix, viewportMatrix, &result1[0], &result1[1], &result1[2]); if (success) { @@ -357,6 +351,10 @@ void Avatar::renderDisplayName() { 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); @@ -370,19 +368,16 @@ void Avatar::renderDisplayName() { QByteArray ba = _displayName.toLocal8Bit(); const char *text = ba.data(); + + glDisable(GL_POLYGON_OFFSET_FILL); textRenderer(DISPLAYNAME)->draw(-_displayNameWidth/2.0, 0, text); + + } glPopMatrix(); - // restore opengl state - if (isLightingEnabled) { - glEnable(GL_LIGHTING); - } - if (isDepthMaskEnabled) { - glDepthMask(true); - } - + glEnable(GL_LIGHTING); } bool Avatar::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance) const { diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index cef6f20b1e..f86afaa090 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -670,10 +670,8 @@ void MyAvatar::updateLookAtTargetAvatar(glm::vec3 &eyePosition) { eyePosition = (avatar->getHead().calculateAverageEyePosition() - avatar->getHead().getScalePivot()) * (avatar->getScale() / avatar->getHead().getScale()) + avatar->getHead().getScalePivot(); _lookAtTargetAvatar = avatarPointer; - avatar->setShowDisplayName(true); return; } else { - avatar->setShowDisplayName(false); } } From a6b202ccbeeb91146ef0f9bc6381167b9d8decf0 Mon Sep 17 00:00:00 2001 From: Jose Carlos Date: Wed, 19 Feb 2014 10:01:15 +0100 Subject: [PATCH 14/26] My Avatar's display name is shown --- interface/src/avatar/Avatar.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 2b7cc94c86..91d91e7219 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -632,10 +632,20 @@ float Avatar::getPelvisToHeadLength() const { } 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; } + } From 64031701e1bf07f9940be817191ef2fa9851439e Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 19 Feb 2014 12:33:05 -0800 Subject: [PATCH 15/26] Added icons for import dialog buttons --- interface/resources/icons/backButton.svg | 18 ++++++++++++++++++ interface/resources/icons/forwardButton.svg | 19 +++++++++++++++++++ interface/resources/icons/toParentButton.svg | 18 ++++++++++++++++++ 3 files changed, 55 insertions(+) create mode 100644 interface/resources/icons/backButton.svg create mode 100644 interface/resources/icons/forwardButton.svg create mode 100644 interface/resources/icons/toParentButton.svg diff --git a/interface/resources/icons/backButton.svg b/interface/resources/icons/backButton.svg new file mode 100644 index 0000000000..0c9fceccc4 --- /dev/null +++ b/interface/resources/icons/backButton.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + diff --git a/interface/resources/icons/forwardButton.svg b/interface/resources/icons/forwardButton.svg new file mode 100644 index 0000000000..73e6439f11 --- /dev/null +++ b/interface/resources/icons/forwardButton.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + diff --git a/interface/resources/icons/toParentButton.svg b/interface/resources/icons/toParentButton.svg new file mode 100644 index 0000000000..cfbe054234 --- /dev/null +++ b/interface/resources/icons/toParentButton.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + From f24cd0ceba270f83d63c8797fa51ffed45c27f7b Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 19 Feb 2014 12:34:38 -0800 Subject: [PATCH 16/26] Added switch to pasteMode after successful import. --- interface/src/Application.cpp | 41 +++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index b316548ad4..6495b17633 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -309,8 +309,13 @@ Application::~Application() { delete idleTimer; Menu::getInstance()->saveSettings(); - _rearMirrorTools->saveSettings(_settings); + + _sharedVoxelSystem.changeTree(new VoxelTree); + if (_voxelImporter) { + _voxelImporter->saveSettings(_settings); + delete _voxelImporter; + } _settings->sync(); // let the avatar mixer know we're out @@ -331,7 +336,6 @@ Application::~Application() { storeSizeAndPosition(); saveScripts(); - _sharedVoxelSystem.changeTree(new VoxelTree); VoxelTreeElement::removeDeleteHook(&_voxels); // we don't need to do this processing on shutdown Menu::getInstance()->deleteLater(); @@ -1296,8 +1300,14 @@ void Application::mousePressEvent(QMouseEvent* event) { pasteVoxels(); } - } else if (event->button() == Qt::RightButton && Menu::getInstance()->isVoxelModeActionChecked()) { - deleteVoxelUnderCursor(); + } else if (event->button() == Qt::RightButton) { + if (Menu::getInstance()->isVoxelModeActionChecked()) { + deleteVoxelUnderCursor(); + } + if (_pasteMode) { + _pasteMode = false; + } + } } } @@ -1707,13 +1717,19 @@ void Application::exportVoxels() { void Application::importVoxels() { if (!_voxelImporter) { _voxelImporter = new VoxelImporter(_window); - _voxelImporter->init(_settings); + _voxelImporter->loadSettings(_settings); } - if (_voxelImporter->exec()) { - qDebug("[DEBUG] Import succeeded."); + if (!_voxelImporter->exec()) { + qDebug() << "[DEBUG] Import succeeded." << endl; + Menu::getInstance()->setIsOptionChecked(MenuOption::VoxelSelectMode, true); + _pasteMode = true; } else { - qDebug("[DEBUG] Import failed."); + qDebug() << "[DEBUG] Import failed." << endl; + if (_sharedVoxelSystem.getTree() == _voxelImporter->getVoxelTree()) { + _sharedVoxelSystem.killLocalVoxels(); + _sharedVoxelSystem.changeTree(&_clipboard); + } } // restore the main window's active state @@ -1770,10 +1786,11 @@ void Application::pasteVoxels() { } pasteVoxelsToOctalCode(octalCodeDestination); - + if (calculatedOctCode) { delete[] calculatedOctCode; } + _pasteMode = false; } void Application::findAxisAlignment() { @@ -1845,6 +1862,7 @@ void Application::init() { VoxelTreeElement::removeUpdateHook(&_sharedVoxelSystem); + // Cleanup of the original shared tree _sharedVoxelSystem.init(); VoxelTree* tmpTree = _sharedVoxelSystem.getTree(); _sharedVoxelSystem.changeTree(&_clipboard); @@ -1936,12 +1954,11 @@ void Application::init() { _audio.init(_glWidget); _rearMirrorTools = new RearMirrorTools(_glWidget, _mirrorViewRect, _settings); + connect(_rearMirrorTools, SIGNAL(closeView()), SLOT(closeMirrorView())); connect(_rearMirrorTools, SIGNAL(restoreView()), SLOT(restoreMirrorView())); connect(_rearMirrorTools, SIGNAL(shrinkView()), SLOT(shrinkMirrorView())); connect(_rearMirrorTools, SIGNAL(resetView()), SLOT(resetSensors())); - - } void Application::closeMirrorView() { @@ -2090,7 +2107,7 @@ void Application::updateMouseVoxels(float deltaTime, float& distance, BoxFace& f PerformanceWarning warn(showWarnings, "Application::updateMouseVoxels()"); _mouseVoxel.s = 0.0f; - bool wasInitialized = _mouseVoxelScaleInitialized; + bool wasInitialized = _mouseVoxelScaleInitialized ; if (Menu::getInstance()->isVoxelModeActionChecked() && (fabs(_myAvatar->getVelocity().x) + fabs(_myAvatar->getVelocity().y) + From 7bce649080064fdbea4638b4c91fc7e971c8a528 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 19 Feb 2014 12:35:45 -0800 Subject: [PATCH 17/26] Fix for voxelImporter --- interface/src/VoxelImporter.cpp | 192 +++++++++++++------------------- interface/src/VoxelImporter.h | 17 ++- 2 files changed, 85 insertions(+), 124 deletions(-) diff --git a/interface/src/VoxelImporter.cpp b/interface/src/VoxelImporter.cpp index 653d04cee4..3949ee96d2 100644 --- a/interface/src/VoxelImporter.cpp +++ b/interface/src/VoxelImporter.cpp @@ -12,6 +12,9 @@ #include #include +const QString SETTINGS_GROUP_NAME = "VoxelImport"; +const QString IMPORT_DIALOG_SETTINGS_KEY = "ImportDialogSettings"; + class ImportTask : public QObject, public QRunnable { public: ImportTask(const QString &filename); @@ -21,18 +24,16 @@ private: QString _filename; }; -const QString SETTINGS_GROUP_NAME = "VoxelImport"; -const QString IMPORT_DIALOG_SETTINGS_KEY = "ImportDialogSettings"; - VoxelImporter::VoxelImporter(QWidget* parent) : QObject(parent), _voxelTree(true), _importDialog(parent), - _currentTask(NULL), - _nextTask(NULL) + _task(NULL), + _didImport(false) { - connect(&_importDialog, &QFileDialog::currentChanged, this, &VoxelImporter::preImport); - connect(&_importDialog, &QFileDialog::accepted, this, &VoxelImporter::import); + connect(&_voxelTree, SIGNAL(importProgress(int)), &_importDialog, SLOT(setProgressBarValue(int))); + connect(&_importDialog, SIGNAL(canceled()), this, SLOT(cancel())); + connect(&_importDialog, SIGNAL(accepted()), this, SLOT(import())); } void VoxelImporter::saveSettings(QSettings* settings) { @@ -41,145 +42,106 @@ void VoxelImporter::saveSettings(QSettings* settings) { settings->endGroup(); } -void VoxelImporter::init(QSettings* settings) { +void VoxelImporter::loadSettings(QSettings* settings) { settings->beginGroup(SETTINGS_GROUP_NAME); _importDialog.restoreState(settings->value(IMPORT_DIALOG_SETTINGS_KEY).toByteArray()); settings->endGroup(); } VoxelImporter::~VoxelImporter() { - if (_nextTask) { - delete _nextTask; - _nextTask = NULL; - } - - if (_currentTask) { - disconnect(_currentTask, 0, 0, 0); - _voxelTree.cancelImport(); - _currentTask = NULL; - } + cleanupTask(); } void VoxelImporter::reset() { _voxelTree.eraseAllOctreeElements(); _importDialog.reset(); - _filename = ""; - if (_nextTask) { - delete _nextTask; - _nextTask = NULL; - } - - if (_currentTask) { - _voxelTree.cancelImport(); - } + cleanupTask(); } int VoxelImporter::exec() { reset(); - - int ret = _importDialog.exec(); - - if (!ret) { - reset(); - } else { - _importDialog.reset(); - - VoxelSystem* voxelSystem = Application::getInstance()->getSharedVoxelSystem(); - - voxelSystem->copySubTreeIntoNewTree(voxelSystem->getTree()->getRoot(), - Application::getInstance()->getClipboard(), - true); - voxelSystem->changeTree(Application::getInstance()->getClipboard()); - } - - return ret; -} - -int VoxelImporter::preImport() { - QString filename = _importDialog.getCurrentFile(); - - if (!QFileInfo(filename).isFile()) { - return 0; - } + _importDialog.exec(); - _filename = filename; - - if (_nextTask) { - delete _nextTask; - } - - _nextTask = new ImportTask(_filename); - connect(_nextTask, SIGNAL(destroyed()), SLOT(launchTask())); - - if (_currentTask != NULL) { - _voxelTree.cancelImport(); - } else { - launchTask(); - } - - return 1; -} - -int VoxelImporter::import() { - QString filename = _importDialog.getCurrentFile(); - - if (!QFileInfo(filename).isFile()) { - _importDialog.reject(); - return 0; - } - - if (_filename == filename) { - if (_currentTask) { - connect(_currentTask, SIGNAL(destroyed()), &_importDialog, SLOT(accept())); - } else { - _importDialog.accept(); - } + if (!_didImport) { + // if the import is rejected, we make sure to cleanup before leaving + cleanupTask(); return 1; - } - - _filename = filename; - - if (_nextTask) { - delete _nextTask; - } - - _nextTask = new ImportTask(_filename); - connect(_nextTask, SIGNAL(destroyed()), SLOT(launchTask())); - connect(_nextTask, SIGNAL(destroyed()), &_importDialog, SLOT(accept())); - - if (_currentTask != NULL) { - _voxelTree.cancelImport(); } else { - launchTask(); + _didImport = false; + return 0; } - - return 1; } -void VoxelImporter::launchTask() { - if (_nextTask != NULL) { - _currentTask = _nextTask; - _nextTask = NULL; +void VoxelImporter::import() { + switch (_importDialog.getMode()) { + case loadingMode: + _importDialog.setMode(placeMode); + return; + case placeMode: + // Means the user chose to import + _didImport = true; + _importDialog.close(); + return; + case importMode: + default: + QString filename = _importDialog.getCurrentFile(); + // if it's not a file, we ignore the call + if (!QFileInfo(filename).isFile()) { + return; + } + + // Let's prepare the dialog window for import + _importDialog.setMode(loadingMode); + + // If not already done, we switch to the local tree + if (Application::getInstance()->getSharedVoxelSystem()->getTree() != &_voxelTree) { + Application::getInstance()->getSharedVoxelSystem()->changeTree(&_voxelTree); + } + + // Creation and launch of the import task on the thread pool + _task = new ImportTask(filename); + connect(_task, SIGNAL(destroyed()), SLOT(import())); + QThreadPool::globalInstance()->start(_task); + break; + } +} - if (Application::getInstance()->getSharedVoxelSystem()->getTree() != &_voxelTree) { - Application::getInstance()->getSharedVoxelSystem()->changeTree(&_voxelTree); - } +void VoxelImporter::cancel() { + switch (_importDialog.getMode()) { + case loadingMode: + disconnect(_task, 0, 0, 0); + cleanupTask(); + case placeMode: + _importDialog.setMode(importMode); + break; + case importMode: + default: + _importDialog.close(); + break; + } +} - QThreadPool::globalInstance()->start(_currentTask); - } else { - _currentTask = NULL; +void VoxelImporter::cleanupTask() { + // If a task is running, we cancel it and put the pointer to null + if (_task) { + _task = NULL; + _voxelTree.cancelImport(); } } ImportTask::ImportTask(const QString &filename) - : _filename(filename) { + : _filename(filename) +{ + setAutoDelete(true); } void ImportTask::run() { VoxelSystem* voxelSystem = Application::getInstance()->getSharedVoxelSystem(); + // We start by cleaning up the shared voxel system just in case voxelSystem->killLocalVoxels(); + // Then we call the righ method for the job if (_filename.endsWith(".png", Qt::CaseInsensitive)) { voxelSystem->readFromSquareARGB32Pixels(_filename.toLocal8Bit().data()); } else if (_filename.endsWith(".svo", Qt::CaseInsensitive)) { @@ -187,8 +149,10 @@ void ImportTask::run() { } else if (_filename.endsWith(".schematic", Qt::CaseInsensitive)) { voxelSystem->readFromSchematicFile(_filename.toLocal8Bit().data()); } else { - qDebug("[ERROR] Invalid file extension."); + // We should never get here. + qDebug() << "[ERROR] Invalid file extension." << endl; } - + + // Here we reaverage the tree so that he is ready for preview voxelSystem->getTree()->reaverageOctreeElements(); } diff --git a/interface/src/VoxelImporter.h b/interface/src/VoxelImporter.h index 43a3835e68..e77abaf18d 100644 --- a/interface/src/VoxelImporter.h +++ b/interface/src/VoxelImporter.h @@ -23,28 +23,25 @@ public: VoxelImporter(QWidget* parent = NULL); ~VoxelImporter(); - void init(QSettings* settings); void reset(); + void loadSettings(QSettings* settings); void saveSettings(QSettings* settings); VoxelTree* getVoxelTree() { return &_voxelTree; } public slots: int exec(); - int preImport(); - int import(); - -private slots: - void launchTask(); + void import(); + void cancel(); private: VoxelTree _voxelTree; ImportDialog _importDialog; - QString _filename; - - ImportTask* _currentTask; - ImportTask* _nextTask; + ImportTask* _task; + bool _didImport; + + void cleanupTask(); }; #endif /* defined(__hifi__VoxelImporter__) */ From 0ed7b959d770fc0e90af2a5361c3e5e0ca5add06 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 19 Feb 2014 12:36:27 -0800 Subject: [PATCH 18/26] Changed import dialog UI --- interface/src/ImportDialog.cpp | 158 ++++++++++++++++----------------- interface/src/ImportDialog.h | 32 ++++--- 2 files changed, 97 insertions(+), 93 deletions(-) diff --git a/interface/src/ImportDialog.cpp b/interface/src/ImportDialog.cpp index c276a4da6b..192e7fbf86 100644 --- a/interface/src/ImportDialog.cpp +++ b/interface/src/ImportDialog.cpp @@ -16,14 +16,13 @@ const QString WINDOW_NAME = QObject::tr("Import Voxels"); const QString IMPORT_BUTTON_NAME = QObject::tr("Import"); +const QString LOADING_BUTTON_NAME = QObject::tr("Loading ..."); +const QString PLACE_BUTTON_NAME = QObject::tr("Place voxels"); const QString IMPORT_INFO = QObject::tr("Import %1 as voxels"); const QString CANCEL_BUTTON_NAME = QObject::tr("Cancel"); -const QString INFO_LABEL_TEXT = QObject::tr("
" - "This will load the selected file into Hifi and allow you
" - "to place it with %1-V; you must be in select or
" - "add mode (S or V keys will toggle mode) to place.
"); -const QString DESKTOP_LOCATION = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); + +const QString DOWNLOAD_LOCATION = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation); const int SHORT_FILE_EXTENSION = 4; const int SECOND_INDEX_LETTER = 1; @@ -66,7 +65,7 @@ QIcon HiFiIconProvider::icon(const QFileInfo &info) const { if (info.isDir()) { if (info.absoluteFilePath() == QDir::homePath()) { return QIcon("resources/icons/home.svg"); - } else if (info.absoluteFilePath() == DESKTOP_LOCATION) { + } else if (info.absoluteFilePath() == QStandardPaths::writableLocation(QStandardPaths::DesktopLocation)) { return QIcon("resources/icons/desktop.svg"); } else if (info.absoluteFilePath() == QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)) { return QIcon("resources/icons/documents.svg"); @@ -95,10 +94,11 @@ QString HiFiIconProvider::type(const QFileInfo &info) const { } ImportDialog::ImportDialog(QWidget* parent) : - QFileDialog(parent, WINDOW_NAME, DESKTOP_LOCATION, NULL), + QFileDialog(parent, WINDOW_NAME, DOWNLOAD_LOCATION, NULL), + _progressBar(this), _importButton(IMPORT_BUTTON_NAME, this), _cancelButton(CANCEL_BUTTON_NAME, this), - fileAccepted(false) { + _mode(importMode) { setOption(QFileDialog::DontUseNativeDialog, true); setFileMode(QFileDialog::ExistingFile); @@ -107,96 +107,89 @@ ImportDialog::ImportDialog(QWidget* parent) : setImportTypes(); setLayout(); - connect(&_importButton, SIGNAL(pressed()), SLOT(import())); - connect(this, SIGNAL(currentChanged(QString)), SLOT(saveCurrentFile(QString))); - - connect(&_cancelButton, SIGNAL(pressed()), SLOT(close())); - connect(this, SIGNAL(currentChanged(QString)), SLOT(saveCurrentFile(QString))); -} - -ImportDialog::~ImportDialog() { - deleteLater(); -} - -void ImportDialog::import() { - fileAccepted = true; - emit accepted(); -} - -void ImportDialog::accept() { - // do nothing if import is not enable - if (!_importButton.isEnabled()) { - return; - } + _progressBar.setRange(0, 100); - if (!fileAccepted) { - fileAccepted = true; - emit accepted(); - } else { - QFileDialog::accept(); - } -} - -void ImportDialog::reject() { - QFileDialog::reject(); -} - -int ImportDialog::exec() { - // deselect selected file - selectFile(" "); - return QFileDialog::exec(); + connect(&_importButton, SIGNAL(pressed()), SLOT(accept())); + connect(&_cancelButton, SIGNAL(pressed()), SIGNAL(canceled())); + connect(this, SIGNAL(currentChanged(QString)), SLOT(saveCurrentFile(QString))); } void ImportDialog::reset() { - _importButton.setEnabled(false); + setMode(importMode); + _progressBar.setValue(0); } -void ImportDialog::saveCurrentFile(QString filename) { - if (!filename.isEmpty() && QFileInfo(filename).isFile()) { - _currentFile = filename; - _importButton.setEnabled(true); - } else { - _currentFile.clear(); - _importButton.setEnabled(false); +void ImportDialog::setMode(dialogMode mode) { + _mode = mode; + + switch (_mode) { + case loadingMode: + _importButton.setEnabled(false); + _importButton.setText(LOADING_BUTTON_NAME); + findChild("sidebar")->setEnabled(false); + findChild("treeView")->setEnabled(false); + findChild("backButton")->setEnabled(false); + findChild("forwardButton")->setEnabled(false); + findChild("toParentButton")->setEnabled(false); + break; + case placeMode: + _progressBar.setValue(100); + _importButton.setEnabled(true); + _importButton.setText(PLACE_BUTTON_NAME); + findChild("sidebar")->setEnabled(false); + findChild("treeView")->setEnabled(false); + findChild("backButton")->setEnabled(false); + findChild("forwardButton")->setEnabled(false); + findChild("toParentButton")->setEnabled(false); + break; + case importMode: + default: + _progressBar.setValue(0); + _importButton.setEnabled(true); + _importButton.setText(IMPORT_BUTTON_NAME); + findChild("sidebar")->setEnabled(true); + findChild("treeView")->setEnabled(true); + findChild("backButton")->setEnabled(true); + findChild("forwardButton")->setEnabled(true); + findChild("toParentButton")->setEnabled(true); + break; } } +void ImportDialog::setProgressBarValue(int value) { + _progressBar.setValue(value); +} + +void ImportDialog::accept() { + emit accepted(); +} + +void ImportDialog::saveCurrentFile(QString filename) { + _currentFile = QFileInfo(filename).isFile() ? filename : ""; +} +#include void ImportDialog::setLayout() { - -#ifdef Q_OS_MAC - QString cmdString = ("Command"); -#else - QString cmdString = ("Control"); -#endif - QLabel* infoLabel = new QLabel(QString(INFO_LABEL_TEXT).arg(cmdString)); - infoLabel->setObjectName("infoLabel"); - QGridLayout* gridLayout = (QGridLayout*) layout(); - gridLayout->addWidget(infoLabel, 2, 0, 2, 1); + gridLayout->addWidget(&_progressBar, 2, 0, 2, 1); gridLayout->addWidget(&_cancelButton, 2, 1, 2, 1); gridLayout->addWidget(&_importButton, 2, 2, 2, 1); - + // set ObjectName used in qss for styling + _progressBar.setObjectName("progressBar"); _importButton.setObjectName("importButton"); _cancelButton.setObjectName("cancelButton"); // set fixed size _importButton.setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); _cancelButton.setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + + _progressBar.setFixedHeight(7); + _progressBar.setTextVisible(false); // hide unused embedded widgets in QFileDialog QWidget* widget = findChild("lookInCombo"); widget->hide(); - - widget = findChild("backButton"); - widget->hide(); - - widget = findChild("forwardButton"); - widget->hide(); - - widget = findChild("toParentButton"); - widget->hide(); - + widget = findChild("newFolderButton"); widget->hide(); @@ -230,8 +223,18 @@ void ImportDialog::setLayout() { widget = findChild("treeView"); widget->setAttribute(Qt::WA_MacShowFocusRect, false); - + switchToResourcesParentIfRequired(); + + QIcon icon = QIcon("resources/icons/backButton.svg"); + QPushButton* button = (QPushButton*) findChild("backButton"); + //button->setIcon(icon); + + button = (QPushButton*) findChild("forwardButton"); + button = (QPushButton*) findChild("toParentButton"); + + + QFile styleSheet("resources/styles/import_dialog.qss"); if (styleSheet.open(QIODevice::ReadOnly)) { setStyleSheet(styleSheet.readAll()); @@ -281,11 +284,6 @@ void ImportDialog::setImportTypes() { setIconProvider(new HiFiIconProvider(iconsMap)); setNameFilter(importFormatsFilterList); -#ifdef Q_OS_MAC - QString cmdString = ("Command"); -#else - QString cmdString = ("Control"); -#endif setLabelText(QFileDialog::LookIn, QString(IMPORT_INFO).arg(importFormatsInfo)); } } diff --git a/interface/src/ImportDialog.h b/interface/src/ImportDialog.h index 5cfc49e51e..910cd8f789 100644 --- a/interface/src/ImportDialog.h +++ b/interface/src/ImportDialog.h @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -26,37 +27,42 @@ public: QHash iconsMap; }; +enum dialogMode { + importMode, + loadingMode, + placeMode +}; + class ImportDialog : public QFileDialog { Q_OBJECT public: ImportDialog(QWidget* parent = NULL); - ~ImportDialog(); - void reset(); - + QString getCurrentFile() const { return _currentFile; } - + dialogMode getMode() const { return _mode; } + void setMode(dialogMode mode); + signals: - void accepted(); - + void canceled(); + public slots: - int exec(); - void import(); - void accept(); - void reject(); + void setProgressBarValue(int value); private slots: - void saveCurrentFile(QString); + void accept(); + void saveCurrentFile(QString filename); private: QString _currentFile; + QProgressBar _progressBar; QPushButton _importButton; QPushButton _cancelButton; - + dialogMode _mode; + void setLayout(); void setImportTypes(); - bool fileAccepted; }; #endif /* defined(__hifi__ImportDialog__) */ From a732cbf3005b7f2b4c2b406211fc64aa0b800054 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 19 Feb 2014 12:37:08 -0800 Subject: [PATCH 19/26] Modified QSS for new UI (QProgressBar) --- interface/resources/styles/import_dialog.qss | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/interface/resources/styles/import_dialog.qss b/interface/resources/styles/import_dialog.qss index dd9761b7ed..e5046f8b77 100644 --- a/interface/resources/styles/import_dialog.qss +++ b/interface/resources/styles/import_dialog.qss @@ -20,12 +20,23 @@ QLabel#infoLabel { color: #666666; } +QProgressBar { + border: 0px; + border-radius: 0px; + background-color: #BFE4E4; + margin-right: 60px; +} + +QProgressBar::chunk { + background-color: #000000; +} + QPushButton { border-width: 0; border-radius: 9px; font-size: 18px; padding: 17px 0px 15px; - width: 107px; + width: 120px; margin-top: 20px; margin-bottom: 18px; } From 4fd735e28fe84ba70dba83757179a402b78c571e Mon Sep 17 00:00:00 2001 From: Jose Carlos Date: Wed, 19 Feb 2014 22:08:47 +0100 Subject: [PATCH 20/26] Added a factor to correct display name position for non default models For the default avatar, the position is wrong --- interface/src/avatar/Avatar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 91d91e7219..031084b11a 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -302,7 +302,7 @@ void Avatar::renderDisplayName() { glDisable(GL_LIGHTING); glPushMatrix(); - glm::vec3 textPosition = getPosition() + getBodyUpDirection() * (getSkeletonHeight() + getHeadHeight()); + 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 From 406768bf120cfda1ca689073f385d86e6d57002d Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 19 Feb 2014 13:13:17 -0800 Subject: [PATCH 21/26] Code style fixes --- interface/src/Application.cpp | 2 +- interface/src/ImportDialog.cpp | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 3e30d5bfb4..bdffcd1dec 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2128,7 +2128,7 @@ void Application::updateMouseVoxels(float deltaTime, float& distance, BoxFace& f PerformanceWarning warn(showWarnings, "Application::updateMouseVoxels()"); _mouseVoxel.s = 0.0f; - bool wasInitialized = _mouseVoxelScaleInitialized ; + bool wasInitialized = _mouseVoxelScaleInitialized; if (Menu::getInstance()->isVoxelModeActionChecked() && (fabs(_myAvatar->getVelocity().x) + fabs(_myAvatar->getVelocity().y) + diff --git a/interface/src/ImportDialog.cpp b/interface/src/ImportDialog.cpp index 192e7fbf86..0911f7c184 100644 --- a/interface/src/ImportDialog.cpp +++ b/interface/src/ImportDialog.cpp @@ -21,7 +21,6 @@ const QString PLACE_BUTTON_NAME = QObject::tr("Place voxels"); const QString IMPORT_INFO = QObject::tr("Import %1 as voxels"); const QString CANCEL_BUTTON_NAME = QObject::tr("Cancel"); - const QString DOWNLOAD_LOCATION = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation); const int SHORT_FILE_EXTENSION = 4; const int SECOND_INDEX_LETTER = 1; @@ -167,7 +166,7 @@ void ImportDialog::accept() { void ImportDialog::saveCurrentFile(QString filename) { _currentFile = QFileInfo(filename).isFile() ? filename : ""; } -#include + void ImportDialog::setLayout() { QGridLayout* gridLayout = (QGridLayout*) layout(); gridLayout->addWidget(&_progressBar, 2, 0, 2, 1); @@ -225,7 +224,6 @@ void ImportDialog::setLayout() { widget->setAttribute(Qt::WA_MacShowFocusRect, false); switchToResourcesParentIfRequired(); - QIcon icon = QIcon("resources/icons/backButton.svg"); QPushButton* button = (QPushButton*) findChild("backButton"); //button->setIcon(icon); @@ -233,8 +231,6 @@ void ImportDialog::setLayout() { button = (QPushButton*) findChild("forwardButton"); button = (QPushButton*) findChild("toParentButton"); - - QFile styleSheet("resources/styles/import_dialog.qss"); if (styleSheet.open(QIODevice::ReadOnly)) { setStyleSheet(styleSheet.readAll()); From ba0b01d02883f43ae79dfd3bc1dd4c5cffcc63ac Mon Sep 17 00:00:00 2001 From: Jose Carlos Date: Wed, 19 Feb 2014 22:51:40 +0100 Subject: [PATCH 22/26] Style changes after ZappoMan's comments --- interface/src/avatar/Avatar.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 031084b11a..f0dbcc8dbc 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -345,7 +345,7 @@ void Avatar::renderDisplayName() { QFontMetrics metrics = textRenderer(DISPLAYNAME)->metrics(); int bottom = -metrics.descent(), top = bottom + metrics.height(); int left = -_displayNameWidth/2, right = _displayNameWidth/2; - int border = 5; + const int border = 5; bottom -= border; left -= border; top += border; @@ -367,10 +367,10 @@ void Avatar::renderDisplayName() { glColor4f(0.93f, 0.93f, 0.93f, _displayNameAlpha); QByteArray ba = _displayName.toLocal8Bit(); - const char *text = ba.data(); + const char* text = ba.data(); glDisable(GL_POLYGON_OFFSET_FILL); - textRenderer(DISPLAYNAME)->draw(-_displayNameWidth/2.0, 0, text); + textRenderer(DISPLAYNAME)->draw(-_displayNameWidth / 2, 0, text); } From 241214ba37bba81fefa409e90e8f10db8fd4bae0 Mon Sep 17 00:00:00 2001 From: Jose Carlos Date: Wed, 19 Feb 2014 23:08:19 +0100 Subject: [PATCH 23/26] Fixed compilation after merged from upstream --- interface/src/avatar/Avatar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 9eb5e0d577..9ff1ec8cb1 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -587,7 +587,7 @@ float Avatar::getSkeletonHeight() const { } float Avatar::getHeadHeight() const { - Extents extents = _head.getFaceModel().getBindExtents(); + Extents extents = getHead()->getFaceModel().getBindExtents(); return extents.maximum.y - extents.minimum.y; } From ee7b5844b84ae7bdc3ac1db44c6913ad556df68c Mon Sep 17 00:00:00 2001 From: Jose Carlos Date: Wed, 19 Feb 2014 23:24:26 +0100 Subject: [PATCH 24/26] Minor cosmetic change --- interface/src/avatar/AvatarManager.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 026a5d6291..d910e51e35 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -6,8 +6,10 @@ // Copyright (c) 2014 HighFidelity, Inc. All rights reserved. // #include + #include #include + #include #include "Application.h" From 44d5b9b2f8f67c65992c25e9830b5938a7063e41 Mon Sep 17 00:00:00 2001 From: Jose Carlos Date: Thu, 20 Feb 2014 00:22:29 +0100 Subject: [PATCH 25/26] cosmetic change --- interface/src/avatar/AvatarManager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index d910e51e35..4cc568cf18 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -7,11 +7,11 @@ // #include +#include + #include #include -#include - #include "Application.h" #include "Avatar.h" #include "Menu.h" From af3e19e6402c643b998e88d5c784dd4f65d2861b Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 19 Feb 2014 16:01:14 -0800 Subject: [PATCH 26/26] Added style and pngs for the buttons --- interface/resources/styles/import_dialog.qss | 15 +++++++++++++ interface/src/ImportDialog.cpp | 23 ++++++++++++-------- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/interface/resources/styles/import_dialog.qss b/interface/resources/styles/import_dialog.qss index e5046f8b77..d7d661399d 100644 --- a/interface/resources/styles/import_dialog.qss +++ b/interface/resources/styles/import_dialog.qss @@ -62,6 +62,21 @@ QPushButton#cancelButton { margin-right: 11px; } +#backButton { + background-image: url(resources/icons/backButton.svg); + border-radius: 0px; +} + +#forwardButton { + background-image: url(resources/icons/forwardButton.svg); + border-radius: 0px; +} + +#toParentButton { + background-image: url(resources/icons/toParentButton.svg); + border-radius: 0px; +} + QSidebar, QTreeView { border: 1px solid #C5C5C5; font-size: 14px; diff --git a/interface/src/ImportDialog.cpp b/interface/src/ImportDialog.cpp index 0911f7c184..2e0173fb9f 100644 --- a/interface/src/ImportDialog.cpp +++ b/interface/src/ImportDialog.cpp @@ -181,9 +181,21 @@ void ImportDialog::setLayout() { // set fixed size _importButton.setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); _cancelButton.setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - - _progressBar.setFixedHeight(7); + _cancelButton.setFlat(true); + int progressBarHeight = 7; + _progressBar.setFixedHeight(progressBarHeight); _progressBar.setTextVisible(false); + + QSize BUTTON_SIZE = QSize(43, 33); + QPushButton* button = (QPushButton*) findChild("backButton"); + button->setIcon(QIcon()); + button->setFixedSize(BUTTON_SIZE); + button = (QPushButton*) findChild("forwardButton"); + button->setIcon(QIcon()); + button->setFixedSize(BUTTON_SIZE); + button = (QPushButton*) findChild("toParentButton"); + button->setIcon(QIcon()); + button->setFixedSize(BUTTON_SIZE); // hide unused embedded widgets in QFileDialog QWidget* widget = findChild("lookInCombo"); @@ -224,13 +236,6 @@ void ImportDialog::setLayout() { widget->setAttribute(Qt::WA_MacShowFocusRect, false); switchToResourcesParentIfRequired(); - QIcon icon = QIcon("resources/icons/backButton.svg"); - QPushButton* button = (QPushButton*) findChild("backButton"); - //button->setIcon(icon); - - button = (QPushButton*) findChild("forwardButton"); - button = (QPushButton*) findChild("toParentButton"); - QFile styleSheet("resources/styles/import_dialog.qss"); if (styleSheet.open(QIODevice::ReadOnly)) { setStyleSheet(styleSheet.readAll());