From 21a15cff2a7d59447c2785c66972f259950269fa Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Tue, 23 Sep 2014 12:50:47 -0700 Subject: [PATCH 1/3] Avatar can look at corrected position when looking at me --- examples/headMove.js | 2 +- interface/src/Application.cpp | 6 +++--- interface/src/Application.h | 3 ++- interface/src/avatar/Head.cpp | 9 +++++++++ interface/src/avatar/Head.h | 7 +++++++ interface/src/avatar/MyAvatar.cpp | 11 +++++++++++ 6 files changed, 33 insertions(+), 5 deletions(-) diff --git a/examples/headMove.js b/examples/headMove.js index 4d432c28b3..894575ead1 100644 --- a/examples/headMove.js +++ b/examples/headMove.js @@ -43,7 +43,7 @@ var noFly = true; var fixedWalkVelocity = true; //var roomLimits = { xMin: 618, xMax: 635.5, zMin: 528, zMax: 552.5 }; -var roomLimits = { xMin: 193.0, xMax: 206.5, zMin: 251.4, zMax: 269.5 }; +var roomLimits = { xMin: 100.0, xMax: 206.5, zMin: 251.4, zMax: 269.5 }; function isInRoom(position) { var BUFFER = 2.0; diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e1ee1333ca..d8fa22ec8f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1882,13 +1882,13 @@ void Application::shrinkMirrorView() { } } -const float HEAD_SPHERE_RADIUS = 0.07f; +const float HEAD_SPHERE_RADIUS = 0.1f; bool Application::isLookingAtMyAvatar(Avatar* avatar) { glm::vec3 theirLookat = avatar->getHead()->getLookAtPosition(); - glm::vec3 myHeadPosition = _myAvatar->getHead()->getPosition(); + glm::vec3 myEyePosition = _myAvatar->getHead()->getEyePosition(); - if (pointInSphere(theirLookat, myHeadPosition, HEAD_SPHERE_RADIUS * _myAvatar->getScale())) { + if (pointInSphere(theirLookat, myEyePosition, HEAD_SPHERE_RADIUS * _myAvatar->getScale())) { return true; } return false; diff --git a/interface/src/Application.h b/interface/src/Application.h index d17bacd413..63dce2dbfc 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -300,6 +300,8 @@ public: ScriptEngine* getScriptEngine(QString scriptHash) { return _scriptEnginesHash.contains(scriptHash) ? _scriptEnginesHash[scriptHash] : NULL; } void setCursorVisible(bool visible); + + bool isLookingAtMyAvatar(Avatar* avatar); signals: @@ -414,7 +416,6 @@ private: void updateCursor(float deltaTime); Avatar* findLookatTargetAvatar(glm::vec3& eyePosition, QUuid &nodeUUID); - bool isLookingAtMyAvatar(Avatar* avatar); void renderLookatIndicator(glm::vec3 pointOfInterest); diff --git a/interface/src/avatar/Head.cpp b/interface/src/avatar/Head.cpp index a06a060b7d..a1f8495f01 100644 --- a/interface/src/avatar/Head.cpp +++ b/interface/src/avatar/Head.cpp @@ -47,6 +47,7 @@ Head::Head(Avatar* owningAvatar) : _deltaLeanSideways(0.f), _deltaLeanForward(0.f), _isCameraMoving(false), + _isLookingAtMe(false), _faceModel(this) { @@ -219,6 +220,14 @@ glm::quat Head::getFinalOrientationInLocalFrame() const { return glm::quat(glm::radians(glm::vec3(getFinalPitch(), getFinalYaw(), getFinalRoll() ))); } +glm::vec3 Head::getCorrectedLookAtPosition() { + if (_isLookingAtMe) { + return getLookAtPosition(); + } else { + return _correctedLookAtPosition; + } +} + glm::quat Head::getCameraOrientation () const { if (OculusManager::isConnected()) { return getOrientation(); diff --git a/interface/src/avatar/Head.h b/interface/src/avatar/Head.h index 58feeff420..1ff6c5d876 100644 --- a/interface/src/avatar/Head.h +++ b/interface/src/avatar/Head.h @@ -63,6 +63,10 @@ public: const glm::vec3& getAngularVelocity() const { return _angularVelocity; } void setAngularVelocity(glm::vec3 angularVelocity) { _angularVelocity = angularVelocity; } + void setCorrectedLookAtPosition(glm::vec3 correctedLookAtPosition) { _correctedLookAtPosition = correctedLookAtPosition; } + glm::vec3 getCorrectedLookAtPosition(); + void clearCorrectedLookAtPosition() { _isLookingAtMe = false; } + float getScale() const { return _scale; } glm::vec3 getPosition() const { return _position; } const glm::vec3& getEyePosition() const { return _eyePosition; } @@ -143,8 +147,11 @@ private: float _deltaLeanForward; bool _isCameraMoving; + bool _isLookingAtMe; FaceModel _faceModel; + glm::vec3 _correctedLookAtPosition; + // private methods void renderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 45ac377dc0..4c75f3482c 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -953,6 +953,7 @@ void MyAvatar::updateLookAtTargetAvatar() { _targetAvatarPosition = glm::vec3(0.0f); const float MIN_LOOKAT_ANGLE = PI / 4.0f; // Smallest angle between face and person where we will look at someone float smallestAngleTo = MIN_LOOKAT_ANGLE; + int howManyLookingAtMe = 0; foreach (const AvatarSharedPointer& avatarPointer, Application::getInstance()->getAvatarManager().getAvatarHash()) { Avatar* avatar = static_cast(avatarPointer.data()); avatar->setIsLookAtTarget(false); @@ -965,11 +966,21 @@ 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 + // TODO: correct to look at left/right eye + avatar->getHead()->setLookAtPosition(Application::getInstance()->getCamera()->getPosition()); + } } } if (_lookAtTargetAvatar) { static_cast(_lookAtTargetAvatar.data())->setIsLookAtTarget(true); } + if (howManyLookingAtMe > 0) { + qDebug() << "look @me: " << howManyLookingAtMe; + } } void MyAvatar::clearLookAtTargetAvatar() { From 75e536235c63fbfd8dd8a6153c2b206eda59d970 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Wed, 24 Sep 2014 14:38:44 -0700 Subject: [PATCH 2/3] Avatars look at your camera, not your avatar. Improvements to lookAt code --- interface/src/Application.cpp | 15 ++++++------- interface/src/Audio.cpp | 20 ++---------------- interface/src/Audio.h | 2 ++ interface/src/avatar/FaceModel.cpp | 2 +- interface/src/avatar/Head.cpp | 11 +++++++--- interface/src/avatar/Head.h | 3 ++- interface/src/avatar/MyAvatar.cpp | 28 +++++++++++++++---------- interface/src/avatar/MyAvatar.h | 2 +- libraries/avatars/src/AvatarHashMap.cpp | 9 +++----- libraries/avatars/src/AvatarHashMap.h | 2 -- 10 files changed, 44 insertions(+), 50 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9397fa063d..3b46b26468 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1890,10 +1890,9 @@ void Application::shrinkMirrorView() { const float HEAD_SPHERE_RADIUS = 0.1f; bool Application::isLookingAtMyAvatar(Avatar* avatar) { - glm::vec3 theirLookat = avatar->getHead()->getLookAtPosition(); + glm::vec3 theirLookAt = avatar->getHead()->getLookAtPosition(); glm::vec3 myEyePosition = _myAvatar->getHead()->getEyePosition(); - - if (pointInSphere(theirLookat, myEyePosition, HEAD_SPHERE_RADIUS * _myAvatar->getScale())) { + if (pointInSphere(theirLookAt, myEyePosition, HEAD_SPHERE_RADIUS * _myAvatar->getScale())) { return true; } return false; @@ -1999,21 +1998,23 @@ void Application::updateMyAvatarLookAtPosition() { lookAtSpot = _myCamera.getPosition(); } else { - if (_myAvatar->getLookAtTargetAvatar() && _myAvatar != _myAvatar->getLookAtTargetAvatar()) { + AvatarSharedPointer lookingAt = _myAvatar->getLookAtTargetAvatar().toStrongRef(); + if (lookingAt && _myAvatar != lookingAt.data()) { + isLookingAtSomeone = true; // If I am looking at someone else, look directly at one of their eyes if (tracker) { // If tracker 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(_myAvatar->getLookAtTargetAvatar())->getHead()->getRightEyePosition(); + lookAtSpot = static_cast(lookingAt.data())->getHead()->getRightEyePosition(); } else { // Look at their left eye - lookAtSpot = static_cast(_myAvatar->getLookAtTargetAvatar())->getHead()->getLeftEyePosition(); + lookAtSpot = static_cast(lookingAt.data())->getHead()->getLeftEyePosition(); } } else { // Need to add randomly looking back and forth between left and right eye for case with no tracker - lookAtSpot = static_cast(_myAvatar->getLookAtTargetAvatar())->getHead()->getEyePosition(); + lookAtSpot = static_cast(lookingAt.data())->getHead()->getEyePosition(); } } else { // I am not looking at anyone else, so just look forward diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index e9cc6f9271..365064e979 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -630,7 +630,7 @@ void Audio::handleAudioInput() { measuredDcOffset += networkAudioSamples[i]; networkAudioSamples[i] -= (int16_t) _dcOffset; thisSample = fabsf(networkAudioSamples[i]); - if (thisSample >= (32767.0f * CLIPPING_THRESHOLD)) { + if (thisSample >= ((float)MAX_16_BIT_AUDIO_SAMPLE * CLIPPING_THRESHOLD)) { _timeSinceLastClip = 0.0f; } loudness += thisSample; @@ -1375,32 +1375,16 @@ int Audio::addBufferToScope(QByteArray* byteArray, int frameOffset, const int16_ return 0; } - // Constant multiplier to map sample value to vertical size of scope - float multiplier = (float)MULTIPLIER_SCOPE_HEIGHT / logf(2.0f); - - // Used to scale each sample. (logf(sample) + fadeOffset) is same as logf(sample * fade). - float fadeOffset = logf(fade); - // Temporary variable receives sample value float sample; - // Temporary variable receives mapping of sample value - int16_t value; - QMutexLocker lock(&_guard); // Short int pointer to mapped samples in byte array int16_t* destination = (int16_t*) byteArray->data(); for (int i = 0; i < sourceSamplesPerChannel; i++) { sample = (float)source[i * sourceNumberOfChannels + sourceChannel]; - if (sample > 1) { - value = (int16_t)(multiplier * (logf(sample) + fadeOffset)); - } else if (sample < -1) { - value = (int16_t)(-multiplier * (logf(-sample) + fadeOffset)); - } else { - value = 0; - } - destination[frameOffset] = value; + destination[frameOffset] = sample / (float) MAX_16_BIT_AUDIO_SAMPLE * (float)SCOPE_HEIGHT / 2.0f; frameOffset = (frameOffset == _samplesPerScope - 1) ? 0 : frameOffset + 1; } return frameOffset; diff --git a/interface/src/Audio.h b/interface/src/Audio.h index f100c04684..e94e5ab16c 100644 --- a/interface/src/Audio.h +++ b/interface/src/Audio.h @@ -47,6 +47,8 @@ static const int NUM_AUDIO_CHANNELS = 2; +static const int MAX_16_BIT_AUDIO_SAMPLE = 32767; + class QAudioInput; class QAudioOutput; diff --git a/interface/src/avatar/FaceModel.cpp b/interface/src/avatar/FaceModel.cpp index d51973f88f..70f59f0661 100644 --- a/interface/src/avatar/FaceModel.cpp +++ b/interface/src/avatar/FaceModel.cpp @@ -64,7 +64,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->getLookAtPosition() + + glm::vec3 lookAt = glm::vec3(inverse * glm::vec4(_owningHead->getCorrectedLookAtPosition() + _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 5e23de1d9c..20f1a59bcc 100644 --- a/interface/src/avatar/Head.cpp +++ b/interface/src/avatar/Head.cpp @@ -200,7 +200,7 @@ void Head::render(float alpha, Model::RenderMode mode) { } void Head::renderPostLighting() { - renderLookatVectors(_leftEyePosition, _rightEyePosition, _lookAtPosition); + renderLookatVectors(_leftEyePosition, _rightEyePosition, getCorrectedLookAtPosition()); } void Head::setScale (float scale) { @@ -220,12 +220,17 @@ glm::quat Head::getFinalOrientationInLocalFrame() const { glm::vec3 Head::getCorrectedLookAtPosition() { if (_isLookingAtMe) { - return getLookAtPosition(); - } else { return _correctedLookAtPosition; + } else { + return getLookAtPosition(); } } +void Head::setCorrectedLookAtPosition(glm::vec3 correctedLookAtPosition) { + _isLookingAtMe = true; + _correctedLookAtPosition = correctedLookAtPosition; +} + glm::quat Head::getCameraOrientation () const { if (OculusManager::isConnected()) { return getOrientation(); diff --git a/interface/src/avatar/Head.h b/interface/src/avatar/Head.h index 1ff6c5d876..a7186dc045 100644 --- a/interface/src/avatar/Head.h +++ b/interface/src/avatar/Head.h @@ -63,9 +63,10 @@ public: const glm::vec3& getAngularVelocity() const { return _angularVelocity; } void setAngularVelocity(glm::vec3 angularVelocity) { _angularVelocity = angularVelocity; } - void setCorrectedLookAtPosition(glm::vec3 correctedLookAtPosition) { _correctedLookAtPosition = correctedLookAtPosition; } + void setCorrectedLookAtPosition(glm::vec3 correctedLookAtPosition); glm::vec3 getCorrectedLookAtPosition(); void clearCorrectedLookAtPosition() { _isLookingAtMe = false; } + bool getIsLookingAtMe() { return _isLookingAtMe; } float getScale() const { return _scale; } glm::vec3 getPosition() const { return _position; } diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index b61c28ac1c..a3fa6f525d 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -951,16 +951,23 @@ void MyAvatar::updateLookAtTargetAvatar() { // _lookAtTargetAvatar.clear(); _targetAvatarPosition = glm::vec3(0.0f); - const float MIN_LOOKAT_ANGLE = PI / 4.0f; // Smallest angle between face and person where we will look at someone - float smallestAngleTo = MIN_LOOKAT_ANGLE; + + glm::quat faceRotation = Application::getInstance()->getViewFrustum()->getOrientation(); + FaceTracker* tracker = Application::getInstance()->getActiveFaceTracker(); + if (tracker) { + // If faceshift or other face tracker in use, add on the actual angle of the head + faceRotation *= tracker->getHeadRotation(); + } + glm::vec3 lookForward = faceRotation * IDENTITY_FRONT; + glm::vec3 cameraPosition = Application::getInstance()->getCamera()->getPosition(); + float smallestAngleTo = glm::radians(Application::getInstance()->getCamera()->getFieldOfView()) / 2.f; + int howManyLookingAtMe = 0; foreach (const AvatarSharedPointer& avatarPointer, Application::getInstance()->getAvatarManager().getAvatarHash()) { Avatar* avatar = static_cast(avatarPointer.data()); avatar->setIsLookAtTarget(false); - if (!avatar->isMyAvatar()) { - glm::vec3 DEFAULT_GAZE_IN_HEAD_FRAME = glm::vec3(0.0f, 0.0f, -1.0f); - float angleTo = glm::angle(getHead()->getFinalOrientationInWorldFrame() * DEFAULT_GAZE_IN_HEAD_FRAME, - glm::normalize(avatar->getHead()->getEyePosition() - getHead()->getEyePosition())); + if (!avatar->isMyAvatar() && avatar->isInitialized()) { + float angleTo = glm::angle(lookForward, glm::normalize(avatar->getHead()->getEyePosition() - cameraPosition)); if (angleTo < smallestAngleTo) { _lookAtTargetAvatar = avatarPointer; _targetAvatarPosition = avatarPointer->getPosition(); @@ -970,17 +977,16 @@ void MyAvatar::updateLookAtTargetAvatar() { if (Application::getInstance()->isLookingAtMyAvatar(avatar)) { howManyLookingAtMe++; // Have that avatar look directly at my camera - // TODO: correct to look at left/right eye - avatar->getHead()->setLookAtPosition(Application::getInstance()->getCamera()->getPosition()); + // Philip TODO: correct to look at left/right eye + avatar->getHead()->setCorrectedLookAtPosition(Application::getInstance()->getCamera()->getPosition()); + } else { + avatar->getHead()->clearCorrectedLookAtPosition(); } } } if (_lookAtTargetAvatar) { static_cast(_lookAtTargetAvatar.data())->setIsLookAtTarget(true); } - if (howManyLookingAtMe > 0) { - qDebug() << "look @me: " << howManyLookingAtMe; - } } void MyAvatar::clearLookAtTargetAvatar() { diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index b5eb7ee1ff..e38f3f4b2b 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -119,7 +119,7 @@ public: Q_INVOKABLE glm::vec3 getEyePosition() const { return getHead()->getEyePosition(); } Q_INVOKABLE glm::vec3 getTargetAvatarPosition() const { return _targetAvatarPosition; } - AvatarData* getLookAtTargetAvatar() const { return _lookAtTargetAvatar.data(); } + QWeakPointer getLookAtTargetAvatar() const { return _lookAtTargetAvatar; } void updateLookAtTargetAvatar(); void clearLookAtTargetAvatar(); diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp index 202121bad3..f996fc2bad 100644 --- a/libraries/avatars/src/AvatarHashMap.cpp +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -21,11 +21,6 @@ AvatarHashMap::AvatarHashMap() : connect(NodeList::getInstance(), &NodeList::uuidChanged, this, &AvatarHashMap::sessionUUIDChanged); } -void AvatarHashMap::insert(const QUuid& sessionUUID, AvatarSharedPointer avatar) { - _avatarHash.insert(sessionUUID, avatar); - avatar->setSessionUUID(sessionUUID); -} - AvatarHash::iterator AvatarHashMap::erase(const AvatarHash::iterator& iterator) { qDebug() << "Removing Avatar with UUID" << iterator.key() << "from AvatarHashMap."; return _avatarHash.erase(iterator); @@ -95,9 +90,11 @@ AvatarSharedPointer AvatarHashMap::matchingOrNewAvatar(const QUuid& sessionUUID, matchingAvatar = newSharedAvatar(); qDebug() << "Adding avatar with sessionUUID " << sessionUUID << "to AvatarHashMap."; - _avatarHash.insert(sessionUUID, matchingAvatar); + matchingAvatar->setSessionUUID(sessionUUID); matchingAvatar->setOwningAvatarMixer(mixerWeakPointer); + + _avatarHash.insert(sessionUUID, matchingAvatar); } return matchingAvatar; diff --git a/libraries/avatars/src/AvatarHashMap.h b/libraries/avatars/src/AvatarHashMap.h index fe9ab3d634..d52c656bc1 100644 --- a/libraries/avatars/src/AvatarHashMap.h +++ b/libraries/avatars/src/AvatarHashMap.h @@ -30,8 +30,6 @@ public: const AvatarHash& getAvatarHash() { return _avatarHash; } int size() const { return _avatarHash.size(); } - - virtual void insert(const QUuid& sessionUUID, AvatarSharedPointer avatar); public slots: void processAvatarMixerDatagram(const QByteArray& datagram, const QWeakPointer& mixerWeakPointer); From fcc5eb9d0af9ffa31c1d76af2bcf0d53e7fad282 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Wed, 24 Sep 2014 16:37:55 -0700 Subject: [PATCH 3/3] Tuning of audio-driven mouths and brows to look better and not stay open --- interface/src/avatar/Head.cpp | 15 +++++++++++++-- interface/src/avatar/Head.h | 1 + interface/src/avatar/MyAvatar.cpp | 2 +- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/interface/src/avatar/Head.cpp b/interface/src/avatar/Head.cpp index 20f1a59bcc..9c41cf8084 100644 --- a/interface/src/avatar/Head.cpp +++ b/interface/src/avatar/Head.cpp @@ -34,6 +34,7 @@ Head::Head(Avatar* owningAvatar) : _lastLoudness(0.0f), _longTermAverageLoudness(-1.0f), _audioAttack(0.0f), + _audioJawOpen(0.0f), _angularVelocity(0,0,0), _renderLookatVectors(false), _saccade(0.0f, 0.0f, 0.0f), @@ -157,11 +158,21 @@ void Head::simulate(float deltaTime, bool isMine, bool billboard) { } // use data to update fake Faceshift blendshape coefficients - const float JAW_OPEN_SCALE = 10.f; + const float JAW_OPEN_SCALE = 0.015f; + const float JAW_OPEN_RATE = 0.9f; + const float JAW_CLOSE_RATE = 0.90f; + float audioDelta = sqrtf(glm::max(_averageLoudness - _longTermAverageLoudness, 0.0f)) * JAW_OPEN_SCALE; + if (audioDelta > _audioJawOpen) { + _audioJawOpen += (audioDelta - _audioJawOpen) * JAW_OPEN_RATE; + } else { + _audioJawOpen *= JAW_CLOSE_RATE; + } + _audioJawOpen = glm::clamp(_audioJawOpen, 0.0f, 1.0f); + Application::getInstance()->getFaceshift()->updateFakeCoefficients(_leftEyeBlink, _rightEyeBlink, _browAudioLift, - glm::clamp(log(_averageLoudness) / JAW_OPEN_SCALE, 0.0f, 1.0f), + _audioJawOpen, _blendshapeCoefficients); } diff --git a/interface/src/avatar/Head.h b/interface/src/avatar/Head.h index a7186dc045..efcee9ed8d 100644 --- a/interface/src/avatar/Head.h +++ b/interface/src/avatar/Head.h @@ -130,6 +130,7 @@ private: float _lastLoudness; float _longTermAverageLoudness; float _audioAttack; + float _audioJawOpen; glm::vec3 _angularVelocity; bool _renderLookatVectors; glm::vec3 _saccade; diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index a3fa6f525d..51f582c4f8 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -978,7 +978,7 @@ void MyAvatar::updateLookAtTargetAvatar() { howManyLookingAtMe++; // Have that avatar look directly at my camera // Philip TODO: correct to look at left/right eye - avatar->getHead()->setCorrectedLookAtPosition(Application::getInstance()->getCamera()->getPosition()); + avatar->getHead()->setCorrectedLookAtPosition(Application::getInstance()->getViewFrustum()->getPosition()); } else { avatar->getHead()->clearCorrectedLookAtPosition(); }