From 9ac4e2f6877f9bd56112b40d1fc39064427c43a8 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 21 Jul 2015 18:22:27 -0700 Subject: [PATCH 1/7] Render spheres over avatar eyes if they're looking at me --- interface/src/avatar/Avatar.cpp | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 3a55e73fa6..f9a1185e24 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -448,36 +448,35 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition, boo } } - // Stack indicator spheres - float indicatorOffset = 0.0f; - if (!_displayName.isEmpty() && _displayNameAlpha != 0.0f) { - const float DISPLAY_NAME_INDICATOR_OFFSET = 0.22f; - indicatorOffset = DISPLAY_NAME_INDICATOR_OFFSET; - } - const float INDICATOR_RADIUS = 0.03f; - const float INDICATOR_INDICATOR_OFFSET = 3.0f * INDICATOR_RADIUS; - // If this is the avatar being looked at, render a little ball above their head if (_isLookAtTarget && Menu::getInstance()->isOptionChecked(MenuOption::RenderFocusIndicator)) { + const float INDICATOR_OFFSET = 0.22f; + const float INDICATOR_RADIUS = 0.03f; const glm::vec4 LOOK_AT_INDICATOR_COLOR = { 0.8f, 0.0f, 0.0f, 0.75f }; - glm::vec3 position = glm::vec3(_position.x, getDisplayNamePosition().y + indicatorOffset, _position.z); + glm::vec3 position = glm::vec3(_position.x, getDisplayNamePosition().y + INDICATOR_OFFSET, _position.z); Transform transform; transform.setTranslation(position); batch.setModelTransform(transform); DependencyManager::get()->renderSolidSphere(batch, INDICATOR_RADIUS, 15, 15, LOOK_AT_INDICATOR_COLOR); - indicatorOffset += INDICATOR_INDICATOR_OFFSET; } - // If the avatar is looking at me, render an indication that they area + // If the avatar is looking at me, indicate that they are if (getHead()->getIsLookingAtMe() && Menu::getInstance()->isOptionChecked(MenuOption::ShowWhosLookingAtMe)) { - const glm::vec4 LOOKING_AT_ME_COLOR = { 0.8f, 0.65f, 0.0f, 0.1f }; - glm::vec3 position = glm::vec3(_position.x, getDisplayNamePosition().y + indicatorOffset, _position.z); + const glm::vec3 LOOKING_AT_ME_COLOR = { 1.0f, 1.0f, 1.0f }; + float alpha = 1.0f; + float radius = 0.035f; Transform transform; + glm::vec3 position = getHead()->getLeftEyePosition(); transform.setTranslation(position); batch.setModelTransform(transform); - DependencyManager::get()->renderSolidSphere(batch, INDICATOR_RADIUS, - 15, 15, LOOKING_AT_ME_COLOR); + DependencyManager::get()->renderSolidSphere(batch, radius, 15, 15, + glm::vec4(LOOKING_AT_ME_COLOR, alpha)); + position = getHead()->getRightEyePosition(); + transform.setTranslation(position); + batch.setModelTransform(transform); + DependencyManager::get()->renderSolidSphere(batch, radius, 15, 15, + glm::vec4(LOOKING_AT_ME_COLOR, alpha)); } // quick check before falling into the code below: From bed266dfe993469cb6252fccf90a6e48e00767a8 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 21 Jul 2015 18:23:50 -0700 Subject: [PATCH 2/7] Fade looking-at-me eye spheres over half a second --- interface/src/avatar/Avatar.cpp | 31 ++++++++++++++++++------------- interface/src/avatar/Head.cpp | 4 ++++ interface/src/avatar/Head.h | 2 ++ 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index f9a1185e24..884540bf7c 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -464,19 +464,24 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition, boo // If the avatar is looking at me, indicate that they are if (getHead()->getIsLookingAtMe() && Menu::getInstance()->isOptionChecked(MenuOption::ShowWhosLookingAtMe)) { const glm::vec3 LOOKING_AT_ME_COLOR = { 1.0f, 1.0f, 1.0f }; - float alpha = 1.0f; - float radius = 0.035f; - Transform transform; - glm::vec3 position = getHead()->getLeftEyePosition(); - transform.setTranslation(position); - batch.setModelTransform(transform); - DependencyManager::get()->renderSolidSphere(batch, radius, 15, 15, - glm::vec4(LOOKING_AT_ME_COLOR, alpha)); - position = getHead()->getRightEyePosition(); - transform.setTranslation(position); - batch.setModelTransform(transform); - DependencyManager::get()->renderSolidSphere(batch, radius, 15, 15, - glm::vec4(LOOKING_AT_ME_COLOR, alpha)); + const float LOOKING_AT_ME_DURATION = 0.5f; // seconds + quint64 now = usecTimestampNow(); + float alpha = 1.0f - ((float)(usecTimestampNow() - getHead()->getIsLookingAtMeStarted())) + / (LOOKING_AT_ME_DURATION * (float)USECS_PER_SECOND); + if (alpha > 0.0f) { + float radius = 0.035f; + Transform transform; + glm::vec3 position = getHead()->getLeftEyePosition(); + transform.setTranslation(position); + batch.setModelTransform(transform); + DependencyManager::get()->renderSolidSphere(batch, radius, 15, 15, + glm::vec4(LOOKING_AT_ME_COLOR, alpha)); + position = getHead()->getRightEyePosition(); + transform.setTranslation(position); + batch.setModelTransform(transform); + DependencyManager::get()->renderSolidSphere(batch, radius, 15, 15, + glm::vec4(LOOKING_AT_ME_COLOR, alpha)); + } } // quick check before falling into the code below: diff --git a/interface/src/avatar/Head.cpp b/interface/src/avatar/Head.cpp index 43e68557ce..94a163e508 100644 --- a/interface/src/avatar/Head.cpp +++ b/interface/src/avatar/Head.cpp @@ -55,6 +55,7 @@ Head::Head(Avatar* owningAvatar) : _deltaLeanForward(0.0f), _isCameraMoving(false), _isLookingAtMe(false), + _isLookingAtMeStarted(0), _faceModel(this), _leftEyeLookAtID(DependencyManager::get()->allocateID()), _rightEyeLookAtID(DependencyManager::get()->allocateID()) @@ -323,6 +324,9 @@ glm::vec3 Head::getCorrectedLookAtPosition() { } void Head::setCorrectedLookAtPosition(glm::vec3 correctedLookAtPosition) { + if (!_isLookingAtMe) { + _isLookingAtMeStarted = usecTimestampNow(); + } _isLookingAtMe = true; _correctedLookAtPosition = correctedLookAtPosition; } diff --git a/interface/src/avatar/Head.h b/interface/src/avatar/Head.h index d7a8462693..58f6f14b0a 100644 --- a/interface/src/avatar/Head.h +++ b/interface/src/avatar/Head.h @@ -53,6 +53,7 @@ public: glm::vec3 getCorrectedLookAtPosition(); void clearCorrectedLookAtPosition() { _isLookingAtMe = false; } bool getIsLookingAtMe() { return _isLookingAtMe; } + quint64 getIsLookingAtMeStarted() { return _isLookingAtMeStarted; } float getScale() const { return _scale; } glm::vec3 getPosition() const { return _position; } @@ -139,6 +140,7 @@ private: bool _isCameraMoving; bool _isLookingAtMe; + quint64 _isLookingAtMeStarted; FaceModel _faceModel; glm::vec3 _correctedLookAtPosition; From 55683e0cd589d353b7367a0aaaace23203d42229 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 21 Jul 2015 18:24:47 -0700 Subject: [PATCH 3/7] Size looking-at-me eye spheres per avatar model dimensions --- interface/src/avatar/Avatar.cpp | 14 +++++++++----- libraries/fbx/src/FBXReader.cpp | 9 ++++++++- libraries/fbx/src/FBXReader.h | 5 ++++- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 884540bf7c..ba0e0126ba 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -469,18 +469,22 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition, boo float alpha = 1.0f - ((float)(usecTimestampNow() - getHead()->getIsLookingAtMeStarted())) / (LOOKING_AT_ME_DURATION * (float)USECS_PER_SECOND); if (alpha > 0.0f) { - float radius = 0.035f; + const float RADIUS_INCREMENT = 0.005f; Transform transform; + glm::vec3 position = getHead()->getLeftEyePosition(); transform.setTranslation(position); batch.setModelTransform(transform); - DependencyManager::get()->renderSolidSphere(batch, radius, 15, 15, - glm::vec4(LOOKING_AT_ME_COLOR, alpha)); + DependencyManager::get()->renderSolidSphere(batch, + getHead()->getFaceModel().getGeometry()->getFBXGeometry().leftEyeSize * _scale / 2.0f + RADIUS_INCREMENT, + 15, 15, glm::vec4(LOOKING_AT_ME_COLOR, alpha)); + position = getHead()->getRightEyePosition(); transform.setTranslation(position); batch.setModelTransform(transform); - DependencyManager::get()->renderSolidSphere(batch, radius, 15, 15, - glm::vec4(LOOKING_AT_ME_COLOR, alpha)); + DependencyManager::get()->renderSolidSphere(batch, + getHead()->getFaceModel().getGeometry()->getFBXGeometry().rightEyeSize * _scale / 2.0f + RADIUS_INCREMENT, + 15, 15, glm::vec4(LOOKING_AT_ME_COLOR, alpha)); } } diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index 4d7bff4df0..466b3de3ee 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -2616,10 +2616,17 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping, buildModelMesh(extracted); # endif + if (extracted.mesh.isEye) { + if (maxJointIndex == geometry.leftEyeJointIndex) { + geometry.leftEyeSize = extracted.mesh.meshExtents.largestDimension() * offsetScale; + } else { + geometry.rightEyeSize = extracted.mesh.meshExtents.largestDimension() * offsetScale; + } + } + geometry.meshes.append(extracted.mesh); int meshIndex = geometry.meshes.size() - 1; meshIDsToMeshIndices.insert(it.key(), meshIndex); - } // now that all joints have been scanned, compute a collision shape for each joint diff --git a/libraries/fbx/src/FBXReader.h b/libraries/fbx/src/FBXReader.h index 200cd4a121..3b3d90eb05 100644 --- a/libraries/fbx/src/FBXReader.h +++ b/libraries/fbx/src/FBXReader.h @@ -232,7 +232,10 @@ public: int rightHandJointIndex = -1; int leftToeJointIndex = -1; int rightToeJointIndex = -1; - + + float leftEyeSize = 0.0f; // Maximum mesh extents dimension + float rightEyeSize = 0.0f; + QVector humanIKJointIndices; glm::vec3 palmDirection; From 87dbbdb2e8a4c740f9c37b76cdd6fcba2c4983c5 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 21 Jul 2015 18:25:35 -0700 Subject: [PATCH 4/7] Set an initial alpha in anticipation of sphere alpha working --- interface/src/avatar/Avatar.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index ba0e0126ba..6aa70196bd 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -464,10 +464,12 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition, boo // If the avatar is looking at me, indicate that they are if (getHead()->getIsLookingAtMe() && Menu::getInstance()->isOptionChecked(MenuOption::ShowWhosLookingAtMe)) { const glm::vec3 LOOKING_AT_ME_COLOR = { 1.0f, 1.0f, 1.0f }; + const float LOOKING_AT_ME_ALPHA_START = 0.8f; const float LOOKING_AT_ME_DURATION = 0.5f; // seconds quint64 now = usecTimestampNow(); - float alpha = 1.0f - ((float)(usecTimestampNow() - getHead()->getIsLookingAtMeStarted())) - / (LOOKING_AT_ME_DURATION * (float)USECS_PER_SECOND); + float alpha = LOOKING_AT_ME_ALPHA_START + * (1.0f - ((float)(usecTimestampNow() - getHead()->getIsLookingAtMeStarted())) + / (LOOKING_AT_ME_DURATION * (float)USECS_PER_SECOND)); if (alpha > 0.0f) { const float RADIUS_INCREMENT = 0.005f; Transform transform; From e44cba500dc90ec00af72269be3a6df90dc06502 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 22 Jul 2015 09:52:49 -0700 Subject: [PATCH 5/7] Guard against head model not being available yet --- interface/src/avatar/Avatar.cpp | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 6aa70196bd..e30c2ac24d 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -471,22 +471,26 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition, boo * (1.0f - ((float)(usecTimestampNow() - getHead()->getIsLookingAtMeStarted())) / (LOOKING_AT_ME_DURATION * (float)USECS_PER_SECOND)); if (alpha > 0.0f) { - const float RADIUS_INCREMENT = 0.005f; - Transform transform; + QSharedPointer geometry = getHead()->getFaceModel().getGeometry(); + if (geometry) { + const float RADIUS_INCREMENT = 0.005f; + Transform transform; - glm::vec3 position = getHead()->getLeftEyePosition(); - transform.setTranslation(position); - batch.setModelTransform(transform); - DependencyManager::get()->renderSolidSphere(batch, - getHead()->getFaceModel().getGeometry()->getFBXGeometry().leftEyeSize * _scale / 2.0f + RADIUS_INCREMENT, - 15, 15, glm::vec4(LOOKING_AT_ME_COLOR, alpha)); + glm::vec3 position = getHead()->getLeftEyePosition(); + transform.setTranslation(position); + batch.setModelTransform(transform); + DependencyManager::get()->renderSolidSphere(batch, + geometry->getFBXGeometry().leftEyeSize * _scale / 2.0f + RADIUS_INCREMENT, 15, 15, + glm::vec4(LOOKING_AT_ME_COLOR, alpha)); - position = getHead()->getRightEyePosition(); - transform.setTranslation(position); - batch.setModelTransform(transform); - DependencyManager::get()->renderSolidSphere(batch, - getHead()->getFaceModel().getGeometry()->getFBXGeometry().rightEyeSize * _scale / 2.0f + RADIUS_INCREMENT, - 15, 15, glm::vec4(LOOKING_AT_ME_COLOR, alpha)); + position = getHead()->getRightEyePosition(); + transform.setTranslation(position); + batch.setModelTransform(transform); + DependencyManager::get()->renderSolidSphere(batch, + geometry->getFBXGeometry().rightEyeSize * _scale / 2.0f + RADIUS_INCREMENT, 15, 15, + glm::vec4(LOOKING_AT_ME_COLOR, alpha)); + + } } } From 9d33cfa9650eabbe07e54bcf027a8145ac083f7b Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 22 Jul 2015 09:53:37 -0700 Subject: [PATCH 6/7] Allow for look-at positions being not quite up to date as avatars move So that looking-at-me indicators don't flicker on when they shouldn't. --- interface/src/avatar/Avatar.cpp | 4 ++-- interface/src/avatar/Head.cpp | 17 +++++++++++++---- interface/src/avatar/Head.h | 9 +++++---- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index e30c2ac24d..1fee720ad4 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -462,13 +462,13 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition, boo } // If the avatar is looking at me, indicate that they are - if (getHead()->getIsLookingAtMe() && Menu::getInstance()->isOptionChecked(MenuOption::ShowWhosLookingAtMe)) { + if (getHead()->isLookingAtMe() && Menu::getInstance()->isOptionChecked(MenuOption::ShowWhosLookingAtMe)) { const glm::vec3 LOOKING_AT_ME_COLOR = { 1.0f, 1.0f, 1.0f }; const float LOOKING_AT_ME_ALPHA_START = 0.8f; const float LOOKING_AT_ME_DURATION = 0.5f; // seconds quint64 now = usecTimestampNow(); float alpha = LOOKING_AT_ME_ALPHA_START - * (1.0f - ((float)(usecTimestampNow() - getHead()->getIsLookingAtMeStarted())) + * (1.0f - ((float)(usecTimestampNow() - getHead()->getLookingAtMeStarted())) / (LOOKING_AT_ME_DURATION * (float)USECS_PER_SECOND)); if (alpha > 0.0f) { QSharedPointer geometry = getHead()->getFaceModel().getGeometry(); diff --git a/interface/src/avatar/Head.cpp b/interface/src/avatar/Head.cpp index 94a163e508..d4ef793ab3 100644 --- a/interface/src/avatar/Head.cpp +++ b/interface/src/avatar/Head.cpp @@ -55,7 +55,8 @@ Head::Head(Avatar* owningAvatar) : _deltaLeanForward(0.0f), _isCameraMoving(false), _isLookingAtMe(false), - _isLookingAtMeStarted(0), + _lookingAtMeStarted(0), + _wasLastLookingAtMe(0), _faceModel(this), _leftEyeLookAtID(DependencyManager::get()->allocateID()), _rightEyeLookAtID(DependencyManager::get()->allocateID()) @@ -316,7 +317,7 @@ glm::quat Head::getFinalOrientationInLocalFrame() const { } glm::vec3 Head::getCorrectedLookAtPosition() { - if (_isLookingAtMe) { + if (isLookingAtMe()) { return _correctedLookAtPosition; } else { return getLookAtPosition(); @@ -324,13 +325,21 @@ glm::vec3 Head::getCorrectedLookAtPosition() { } void Head::setCorrectedLookAtPosition(glm::vec3 correctedLookAtPosition) { - if (!_isLookingAtMe) { - _isLookingAtMeStarted = usecTimestampNow(); + if (!isLookingAtMe()) { + _lookingAtMeStarted = usecTimestampNow(); } _isLookingAtMe = true; + _wasLastLookingAtMe = usecTimestampNow(); _correctedLookAtPosition = correctedLookAtPosition; } +bool Head::isLookingAtMe() { + // Allow for outages such as may be encountered during avatar movement + quint64 now = usecTimestampNow(); + const quint64 LOOKING_AT_ME_GAP_ALLOWED = 1000000; // microseconds + return _isLookingAtMe || (now - _wasLastLookingAtMe) < LOOKING_AT_ME_GAP_ALLOWED; +} + glm::quat Head::getCameraOrientation() const { // NOTE: Head::getCameraOrientation() is not used for orienting the camera "view" while in Oculus mode, so // you may wonder why this code is here. This method will be called while in Oculus mode to determine how diff --git a/interface/src/avatar/Head.h b/interface/src/avatar/Head.h index 58f6f14b0a..a8161d1c7b 100644 --- a/interface/src/avatar/Head.h +++ b/interface/src/avatar/Head.h @@ -52,9 +52,9 @@ public: void setCorrectedLookAtPosition(glm::vec3 correctedLookAtPosition); glm::vec3 getCorrectedLookAtPosition(); void clearCorrectedLookAtPosition() { _isLookingAtMe = false; } - bool getIsLookingAtMe() { return _isLookingAtMe; } - quint64 getIsLookingAtMeStarted() { return _isLookingAtMeStarted; } - + bool isLookingAtMe(); + quint64 getLookingAtMeStarted() { return _lookingAtMeStarted; } + float getScale() const { return _scale; } glm::vec3 getPosition() const { return _position; } const glm::vec3& getEyePosition() const { return _eyePosition; } @@ -140,7 +140,8 @@ private: bool _isCameraMoving; bool _isLookingAtMe; - quint64 _isLookingAtMeStarted; + quint64 _lookingAtMeStarted; + quint64 _wasLastLookingAtMe; FaceModel _faceModel; glm::vec3 _correctedLookAtPosition; From 7c4f6b665bcd614cc6739fd1e28531621385cec4 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 23 Jul 2015 11:04:58 -0700 Subject: [PATCH 7/7] Use a default eye diameter for models without eyes, e.g., the masks --- interface/src/avatar/Avatar.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index bf41449f13..9f457e558d 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -468,22 +468,29 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { if (alpha > 0.0f) { QSharedPointer geometry = getHead()->getFaceModel().getGeometry(); if (geometry) { + const float DEFAULT_EYE_DIAMETER = 0.048f; // Typical human eye const float RADIUS_INCREMENT = 0.005f; Transform transform; glm::vec3 position = getHead()->getLeftEyePosition(); transform.setTranslation(position); batch.setModelTransform(transform); - DependencyManager::get()->renderSolidSphere(batch, - geometry->getFBXGeometry().leftEyeSize * _scale / 2.0f + RADIUS_INCREMENT, 15, 15, - glm::vec4(LOOKING_AT_ME_COLOR, alpha)); + float eyeDiameter = geometry->getFBXGeometry().leftEyeSize; + if (eyeDiameter == 0.0f) { + eyeDiameter = DEFAULT_EYE_DIAMETER; + } + DependencyManager::get()->renderSolidSphere(batch, + eyeDiameter * _scale / 2.0f + RADIUS_INCREMENT, 15, 15, glm::vec4(LOOKING_AT_ME_COLOR, alpha)); position = getHead()->getRightEyePosition(); transform.setTranslation(position); batch.setModelTransform(transform); - DependencyManager::get()->renderSolidSphere(batch, - geometry->getFBXGeometry().rightEyeSize * _scale / 2.0f + RADIUS_INCREMENT, 15, 15, - glm::vec4(LOOKING_AT_ME_COLOR, alpha)); + eyeDiameter = geometry->getFBXGeometry().rightEyeSize; + if (eyeDiameter == 0.0f) { + eyeDiameter = DEFAULT_EYE_DIAMETER; + } + DependencyManager::get()->renderSolidSphere(batch, + eyeDiameter * _scale / 2.0f + RADIUS_INCREMENT, 15, 15, glm::vec4(LOOKING_AT_ME_COLOR, alpha)); } }