From bc4c6351068e81c8d4171ac7e7f5c6a0aa260089 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 1 Jul 2015 18:31:16 -0700 Subject: [PATCH] Fix gazing at avatar (when no head tracking or HMD) Randomly look at avatar's left and right eyes if the face is visible. Otherwise just look at their head. --- interface/src/Application.cpp | 28 ++++++++++++++++++++-------- interface/src/avatar/FaceModel.cpp | 2 +- interface/src/avatar/Head.cpp | 4 ++-- interface/src/avatar/MyAvatar.cpp | 16 ---------------- 4 files changed, 23 insertions(+), 27 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 6975f13291..acc34cbc19 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2294,22 +2294,34 @@ void Application::updateMyAvatarLookAtPosition() { AvatarSharedPointer lookingAt = _myAvatar->getLookAtTargetAvatar().lock(); if (lookingAt && _myAvatar != lookingAt.get()) { isLookingAtSomeone = true; + Head* lookingAtHead = static_cast(lookingAt.get())->getHead(); + // If I am looking at someone else, look directly at one of their eyes if (tracker && !tracker->isMuted()) { // If a face tracker is active, look at the eye for the side my gaze is biased toward if (tracker->getEstimatedEyeYaw() > _myAvatar->getHead()->getFinalYaw()) { - // Look at their right eye - lookAtSpot = static_cast(lookingAt.get())->getHead()->getRightEyePosition(); + lookAtSpot = lookingAtHead->getRightEyePosition(); } else { - // Look at their left eye - lookAtSpot = static_cast(lookingAt.get())->getHead()->getLeftEyePosition(); + lookAtSpot = lookingAtHead->getLeftEyePosition(); } } else { - // Need to add randomly looking back and forth between left and right eye for case with no tracker - if (_myAvatar->isLookingAtLeftEye()) { - lookAtSpot = static_cast(lookingAt.get())->getHead()->getLeftEyePosition(); + + const float MAXIMUM_FACE_ANGLE = 65.0f * RADIANS_PER_DEGREE; + glm::vec3 lookingAtFaceOrientation = lookingAtHead->getFinalOrientationInWorldFrame() * IDENTITY_FRONT; + glm::vec3 fromLookingAtToMe = glm::normalize(_myAvatar->getHead()->getEyePosition() + - lookingAtHead->getEyePosition()); + float faceAngle = glm::angle(lookingAtFaceOrientation, fromLookingAtToMe); + + if (faceAngle < MAXIMUM_FACE_ANGLE) { + // Randomly look back and forth between left and right eyes + if (_myAvatar->isLookingAtLeftEye()) { + lookAtSpot = lookingAtHead->getLeftEyePosition(); + } else { + lookAtSpot = lookingAtHead->getRightEyePosition(); + } } else { - lookAtSpot = static_cast(lookingAt.get())->getHead()->getRightEyePosition(); + // Just look at their head (mid point between eyes) + lookAtSpot = lookingAtHead->getEyePosition(); } } } else { diff --git a/interface/src/avatar/FaceModel.cpp b/interface/src/avatar/FaceModel.cpp index 1501c52de5..7a582406a4 100644 --- a/interface/src/avatar/FaceModel.cpp +++ b/interface/src/avatar/FaceModel.cpp @@ -77,7 +77,7 @@ void FaceModel::maybeUpdateEyeRotation(Model* model, const JointState& parentSta glm::translate(state.getDefaultTranslationInConstrainedFrame()) * joint.preTransform * glm::mat4_cast(joint.preRotation * joint.rotation)); glm::vec3 front = glm::vec3(inverse * glm::vec4(_owningHead->getFinalOrientationInWorldFrame() * IDENTITY_FRONT, 0.0f)); - glm::vec3 lookAt = glm::vec3(inverse * glm::vec4(_owningHead->getCorrectedLookAtPosition() + + glm::vec3 lookAt = glm::vec3(inverse * glm::vec4(_owningHead->getLookAtPosition() + _owningHead->getSaccade() - model->getTranslation(), 1.0f)); glm::quat between = rotationBetween(front, lookAt); const float MAX_ANGLE = 30.0f * RADIANS_PER_DEGREE; diff --git a/interface/src/avatar/Head.cpp b/interface/src/avatar/Head.cpp index 02d16a1ca4..61f378c536 100644 --- a/interface/src/avatar/Head.cpp +++ b/interface/src/avatar/Head.cpp @@ -256,7 +256,7 @@ void Head::calculateMouthShapes() { void Head::applyEyelidOffset(glm::quat headOrientation) { // Adjusts the eyelid blendshape coefficients so that the eyelid follows the iris as the head pitches. - glm::quat eyeRotation = rotationBetween(headOrientation * IDENTITY_FRONT, getCorrectedLookAtPosition() - _eyePosition); + glm::quat eyeRotation = rotationBetween(headOrientation * IDENTITY_FRONT, getLookAtPosition() - _eyePosition); eyeRotation = eyeRotation * glm::angleAxis(safeEulerAngles(headOrientation).y, IDENTITY_UP); // Rotation w.r.t. head float eyePitch = safeEulerAngles(eyeRotation).x; @@ -295,7 +295,7 @@ void Head::relaxLean(float deltaTime) { void Head::render(RenderArgs* renderArgs, float alpha, ViewFrustum* renderFrustum, bool postLighting) { if (postLighting) { if (_renderLookatVectors) { - renderLookatVectors(renderArgs, _leftEyePosition, _rightEyePosition, getCorrectedLookAtPosition()); + renderLookatVectors(renderArgs, _leftEyePosition, _rightEyePosition, getLookAtPosition()); } } } diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index e4ed55601a..f0bba200fe 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -880,7 +880,6 @@ void MyAvatar::updateLookAtTargetAvatar() { const float KEEP_LOOKING_AT_CURRENT_ANGLE_FACTOR = 1.3f; const float GREATEST_LOOKING_AT_DISTANCE = 10.0f; - int howManyLookingAtMe = 0; foreach (const AvatarSharedPointer& avatarPointer, DependencyManager::get()->getAvatarHash()) { Avatar* avatar = static_cast(avatarPointer.get()); bool isCurrentTarget = avatar->getIsLookAtTarget(); @@ -893,21 +892,6 @@ void MyAvatar::updateLookAtTargetAvatar() { _targetAvatarPosition = avatarPointer->getPosition(); smallestAngleTo = angleTo; } - // Check if this avatar is looking at me, and fix their gaze on my camera if so - if (Application::getInstance()->isLookingAtMyAvatar(avatar)) { - howManyLookingAtMe++; - // Have that avatar look directly at my camera - // Philip TODO: correct to look at left/right eye - if (qApp->isHMDMode()) { - avatar->getHead()->setCorrectedLookAtPosition(Application::getInstance()->getViewFrustum()->getPosition()); - // FIXME what is the point of this? - // avatar->getHead()->setCorrectedLookAtPosition(OculusManager::getLeftEyePosition()); - } else { - avatar->getHead()->setCorrectedLookAtPosition(Application::getInstance()->getViewFrustum()->getPosition()); - } - } else { - avatar->getHead()->clearCorrectedLookAtPosition(); - } } } auto avatarPointer = _lookAtTargetAvatar.lock();