From a4fcb2c39e1fcc93df6c0d3883929580704b1a10 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Mon, 21 Oct 2019 14:31:15 -0700 Subject: [PATCH] Add eyesLookAtTarget set/get API methods --- interface/src/Application.cpp | 6 +++--- interface/src/Application.h | 2 +- interface/src/avatar/MyAvatar.cpp | 26 +++++++++++++++++++++++--- interface/src/avatar/MyAvatar.h | 23 +++++++++++++++++++++-- 4 files changed, 48 insertions(+), 9 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 4766353eba..7c0e822bed 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5814,14 +5814,14 @@ void Application::pushPostUpdateLambda(void* key, const std::function& f // to everyone. // The principal result is to call updateLookAtTargetAvatar() and then setLookAtPosition(). // Note that it is called BEFORE we update position or joints based on sensors, etc. -void Application::updateMyAvatarLookAtPosition() { +void Application::updateMyAvatarLookAtPosition(float deltaTime) { PerformanceTimer perfTimer("lookAt"); bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); PerformanceWarning warn(showWarnings, "Application::updateMyAvatarLookAtPosition()"); auto myAvatar = getMyAvatar(); FaceTracker* faceTracker = getActiveFaceTracker(); - myAvatar->updateLookAtPosition(faceTracker, _myCamera); + myAvatar->updateEyesLookAtPosition(faceTracker, _myCamera, deltaTime); } void Application::updateThreads(float deltaTime) { @@ -6605,7 +6605,7 @@ void Application::update(float deltaTime) { { PROFILE_RANGE(simulation, "MyAvatar"); PerformanceTimer perfTimer("MyAvatar"); - qApp->updateMyAvatarLookAtPosition(); + qApp->updateMyAvatarLookAtPosition(deltaTime); avatarManager->updateMyAvatar(deltaTime); } } diff --git a/interface/src/Application.h b/interface/src/Application.h index af2348d1e9..2bb6c5ddb4 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -298,7 +298,7 @@ public: virtual void pushPostUpdateLambda(void* key, const std::function& func) override; - void updateMyAvatarLookAtPosition(); + void updateMyAvatarLookAtPosition(float deltaTime); float getGameLoopRate() const { return _gameLoopCounter.rate(); } diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 2bc0ae32d4..e152902b47 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -2284,7 +2284,9 @@ void MyAvatar::updateLookAtTargetAvatar() { AvatarHash hash = DependencyManager::get()->getHashCopy(); // determine what the best look at target for my avatar should be. - computeMyLookAtTarget(hash); + if (!_scriptControlsEyesLookAt) { + computeMyLookAtTarget(hash); + } // snap look at position for avatars that are looking at me. snapOtherAvatarLookAtTargetsToMe(hash); @@ -6617,7 +6619,7 @@ bool MyAvatar::getIsJointOverridden(int jointIndex) const { return _skeletonModel->getIsJointOverridden(jointIndex); } -void MyAvatar::updateLookAtPosition(FaceTracker* faceTracker, Camera& myCamera) { +void MyAvatar::updateEyesLookAtPosition(FaceTracker* faceTracker, Camera& myCamera, float deltaTime) { updateLookAtTargetAvatar(); @@ -6647,6 +6649,13 @@ void MyAvatar::updateLookAtPosition(FaceTracker* faceTracker, Camera& myCamera) } else { lookAtSpot = myHead->getEyePosition() + glm::normalize(leftVec) * 1000.0f; } + } else if (_scriptControlsEyesLookAt) { + if (_scriptEyesControlTimer < MAX_LOOK_AT_TIME_SCRIPT_CONTROL) { + _scriptEyesControlTimer += deltaTime; + lookAtSpot = _eyesLookAtTarget; + } else { + _scriptControlsEyesLookAt = false; + } } else { controller::Pose leftEyePose = getControllerPoseInAvatarFrame(controller::Action::LEFT_EYE); controller::Pose rightEyePose = getControllerPoseInAvatarFrame(controller::Action::RIGHT_EYE); @@ -6731,7 +6740,7 @@ void MyAvatar::updateLookAtPosition(FaceTracker* faceTracker, Camera& myCamera) } } } - + _eyesLookAtTarget = lookAtSpot; getHead()->setLookAtPosition(lookAtSpot); } @@ -6814,6 +6823,17 @@ void MyAvatar::setHeadLookAt(const glm::vec3& lookAtTarget) { _lookAtScriptTarget = lookAtTarget; } +void MyAvatar::setEyesLookAt(const glm::vec3& lookAtTarget) { + if (QThread::currentThread() != thread()) { + BLOCKING_INVOKE_METHOD(this, "setEyesLookAt", + Q_ARG(const glm::vec3&, lookAtTarget)); + return; + } + _eyesLookAtTarget = lookAtTarget; + _scriptEyesControlTimer = 0.0f; + _scriptControlsEyesLookAt = true; +} + glm::vec3 MyAvatar::getLookAtPivotPoint() { glm::vec3 avatarUp = getWorldOrientation() * Vectors::UP; glm::vec3 yAxisEyePosition = getWorldPosition() + avatarUp * glm::dot(avatarUp, _skeletonModel->getDefaultEyeModelPosition()); diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 3f91222392..90c4157c3c 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -1762,10 +1762,26 @@ public: /**jsdoc * Returns the current head look at target point in world coordinates. * @function MyAvatar.getHeadLookAt - * @returns {Vec3} Default position between your avatar's eyes in world coordinates. + * @returns {Vec3} The head's look at target in world coordinates. */ Q_INVOKABLE glm::vec3 getHeadLookAt() { return _lookAtCameraTarget; } + /**jsdoc + * Force the avatar's eyes to look to the specified location. + * Once this method is called, API calls will have full control of the eyes for a limited time. + * If this method is not called for two seconds, the engine will regain control of the eyes. + * @function MyAvatar.setEyesLookAt + * @param {Vec3} lookAtTarget - The target point in world coordinates. + */ + Q_INVOKABLE void setEyesLookAt(const glm::vec3& lookAtTarget); + + /**jsdoc + * Returns the current eyes look at target point in world coordinates. + * @function MyAvatar.getEyesLookAt + * @returns {Vec3} The eyes's look at target in world coordinates. + */ + Q_INVOKABLE glm::vec3 getEyesLookAt() { return _eyesLookAtTarget; } + /**jsdoc * Aims the pointing directional blending towards the provided target point. * The "point" reaction should be triggered before using this method. @@ -1903,7 +1919,7 @@ public: bool getFlowActive() const; bool getNetworkGraphActive() const; - void updateLookAtPosition(FaceTracker* faceTracker, Camera& myCamera); + void updateEyesLookAtPosition(FaceTracker* faceTracker, Camera& myCamera, float deltaTime); // sets the reaction enabled and triggered parameters of the passed in params // also clears internal reaction triggers @@ -2662,6 +2678,9 @@ private: eyeContactTarget _eyeContactTarget; float _eyeContactTargetTimer { 0.0f }; + glm::vec3 _eyesLookAtTarget; + bool _scriptControlsEyesLookAt{ false }; + float _scriptEyesControlTimer{ 0.0f }; glm::vec3 _trackedHeadPosition;