From 0fac1e134f1fb0a66a1a8d6b54785646f56e7039 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Mon, 30 Sep 2019 16:43:02 -0700 Subject: [PATCH] Allow avatar look at when in first person camera --- interface/src/Application.cpp | 17 ++++------ interface/src/avatar/MyAvatar.cpp | 53 ++++++++++++++++++++++--------- interface/src/avatar/MyAvatar.h | 1 + 3 files changed, 46 insertions(+), 25 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 6a320e53ee..7c08f7d978 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3601,10 +3601,9 @@ void Application::updateCamera(RenderArgs& renderArgs, float deltaTime) { mat4 camMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); _myCamera.setPosition(extractTranslation(camMat)); _myCamera.setOrientation(glmExtractRotation(camMat)); - } - else { - _myCamera.setPosition(myAvatar->getDefaultEyePosition()); - _myCamera.setOrientation(myAvatar->getMyHead()->getHeadOrientation()); + } else { + _myCamera.setPosition(myAvatar->getLookAtPivotPoint()); + _myCamera.setOrientation(myAvatar->getLookAtRotation()); } } else if (mode == CAMERA_MODE_THIRD_PERSON || mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE) { if (isHMDMode()) { @@ -3638,9 +3637,9 @@ void Application::updateCamera(RenderArgs& renderArgs, float deltaTime) { if (mode == CAMERA_MODE_SELFIE) { lookAtRotation = lookAtRotation * glm::angleAxis(PI, myAvatar->getWorldOrientation() * Vectors::UP); } - _myCamera.setPosition(myAvatar->getDefaultEyePosition() + _myCamera.setPosition(myAvatar->getLookAtPivotPoint() + lookAtRotation * boomOffset); - _myCamera.lookAt(myAvatar->getDefaultEyePosition()); + _myCamera.lookAt(myAvatar->getLookAtPivotPoint()); } } } else if (mode == CAMERA_MODE_MIRROR) { @@ -3668,8 +3667,7 @@ void Application::updateCamera(RenderArgs& renderArgs, float deltaTime) { + glm::vec3(0, _raiseMirror * myAvatar->getModelScale(), 0) + mirrorBodyOrientation * glm::vec3(0.0f, 0.0f, 1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror + mirrorBodyOrientation * hmdOffset); - } - else { + } else { auto userInputMapper = DependencyManager::get(); const float YAW_SPEED = TWO_PI / 5.0f; float deltaYaw = userInputMapper->getActionState(controller::Action::YAW) * YAW_SPEED * deltaTime; @@ -3690,8 +3688,7 @@ void Application::updateCamera(RenderArgs& renderArgs, float deltaTime) { _myCamera.setOrientation(cameraEntity->getWorldOrientation() * hmdRotation); glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix()); _myCamera.setPosition(cameraEntity->getWorldPosition() + (hmdRotation * hmdOffset)); - } - else { + } else { _myCamera.setOrientation(cameraEntity->getWorldOrientation()); _myCamera.setPosition(cameraEntity->getWorldPosition()); } diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 6f16e6e1bf..8728c2bd80 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -953,7 +953,7 @@ void MyAvatar::simulate(float deltaTime, bool inView) { head->setScale(getModelScale()); head->simulate(deltaTime); CameraMode mode = qApp->getCamera().getMode(); - if (_scriptControlsHeadLookAt || mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE) { + if (_scriptControlsHeadLookAt || mode == CAMERA_MODE_FIRST_PERSON || mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE) { updateHeadLookAt(deltaTime); } else if (_headLookAtActive){ resetHeadLookAt(); @@ -3429,8 +3429,10 @@ void MyAvatar::updateOrientation(float deltaTime) { // Smoothly rotate body with arrow keys float targetSpeed = getDriveKey(YAW) * _yawSpeed; CameraMode mode = qApp->getCamera().getMode(); - bool computeLookAt = (mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE) && isReadyForPhysics() && !qApp->isHMDMode(); - if (computeLookAt) { + bool computeLookAt = isReadyForPhysics() && !qApp->isHMDMode() && + (mode == CAMERA_MODE_FIRST_PERSON || mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE); + bool smoothCameraYaw = computeLookAt && mode != CAMERA_MODE_FIRST_PERSON; + if (smoothCameraYaw) { // For "Look At" and "Selfie" camera modes we also smooth the yaw rotation from right-click mouse movement. float speedFromDeltaYaw = deltaTime > FLT_EPSILON ? getDriveKey(DELTA_YAW) / deltaTime : 0.0f; speedFromDeltaYaw *= _yawSpeed / YAW_SPEED_DEFAULT; @@ -3459,7 +3461,7 @@ void MyAvatar::updateOrientation(float deltaTime) { } } float totalBodyYaw = _bodyYawDelta * deltaTime; - if (!computeLookAt) { + if (!smoothCameraYaw) { // Rotate directly proportional to delta yaw and delta pitch from right-click mouse movement. totalBodyYaw += getDriveKey(DELTA_YAW) * _yawSpeed / YAW_SPEED_DEFAULT; } @@ -3546,12 +3548,16 @@ void MyAvatar::updateOrientation(float deltaTime) { blend = 1.0f; } glm::quat faceRotation = _lookAtYaw; - if (isMovingFwdBwd && isMovingSideways) { - // Reorient avatar to face camera diagonal - blend = DIAGONAL_TURN_BLEND; - float turnSign = getDriveKey(TRANSLATE_Z) < 0.0f ? -1.0f : 1.0f; - turnSign = getDriveKey(TRANSLATE_X) > 0.0f ? -turnSign : turnSign; - faceRotation = _lookAtYaw * glm::angleAxis(turnSign * 0.25f * PI, Vectors::UP); + if (isMovingFwdBwd) { + if (isMovingSideways) { + // Reorient avatar to face camera diagonal + blend = mode == CAMERA_MODE_FIRST_PERSON ? 1.0f : DIAGONAL_TURN_BLEND; + float turnSign = getDriveKey(TRANSLATE_Z) < 0.0f ? -1.0f : 1.0f; + turnSign = getDriveKey(TRANSLATE_X) > 0.0f ? -turnSign : turnSign; + faceRotation = _lookAtYaw * glm::angleAxis(turnSign * 0.25f * PI, Vectors::UP); + } else if (mode == CAMERA_MODE_FIRST_PERSON) { + blend = 1.0f; + } } setWorldOrientation(glm::slerp(getWorldOrientation(), faceRotation, blend)); } else if (isRotatingWhileSeated) { @@ -3615,11 +3621,21 @@ void MyAvatar::updateOrientation(float deltaTime) { const float REORIENT_ANGLE = 65.0f; const float TRIGGER_REORIENT_ANGLE = 45.0f; + const float FIRST_PERSON_TRIGGER_REORIENT_ANGLE = 45.0f; glm::vec3 ajustedYawVector = cameraYawVector; - if (frontBackDot < 0.0f) { - ajustedYawVector = (leftRightDot < 0.0f ? -avatarVectorRight : avatarVectorRight); - cameraVector = (ajustedYawVector * _lookAtPitch) * Vectors::FRONT; - if (frontBackDot < -glm::sin(glm::radians(TRIGGER_REORIENT_ANGLE))) { + float limitAngle = 0.0f; + float triggerAngle = -glm::sin(glm::radians(TRIGGER_REORIENT_ANGLE)); + if (mode == CAMERA_MODE_FIRST_PERSON) { + limitAngle = glm::sin(glm::radians(FIRST_PERSON_TRIGGER_REORIENT_ANGLE)); + triggerAngle = limitAngle; + } + + if (frontBackDot < limitAngle) { + if (frontBackDot < 0.0f) { + ajustedYawVector = (leftRightDot < 0.0f ? -avatarVectorRight : avatarVectorRight); + cameraVector = (ajustedYawVector * _lookAtPitch) * Vectors::FRONT; + } + if (frontBackDot < triggerAngle) { _shouldTurnToFaceCamera = true; } } else if (frontBackDot > glm::sin(glm::radians(REORIENT_ANGLE))) { @@ -3716,7 +3732,8 @@ glm::vec3 MyAvatar::scaleMotorSpeed(const glm::vec3 forward, const glm::vec3 rig } else { // Desktop mode. direction = (zSpeed * forward) + (xSpeed * right); - if (qApp->getCamera().getMode() == CAMERA_MODE_LOOK_AT && zSpeed != 0.0f && xSpeed != 0.0f){ + CameraMode mode = qApp->getCamera().getMode(); + if ((mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_FIRST_PERSON || mode == CAMERA_MODE_SELFIE) && zSpeed != 0.0f && xSpeed != 0.0f){ direction = (zSpeed * forward); } @@ -6732,3 +6749,9 @@ void MyAvatar::setHeadLookAt(const glm::vec3& lookAtTarget) { _scriptHeadControlTimer = 0.0f; _lookAtScriptTarget = lookAtTarget; } + +glm::vec3 MyAvatar::getLookAtPivotPoint() { + glm::vec3 avatarUp = getWorldOrientation() * Vectors::UP; + glm::vec3 yAxisEyePosition = getWorldPosition() + avatarUp * glm::dot(avatarUp, _skeletonModel->getDefaultEyeModelPosition()); + return yAxisEyePosition; +} \ No newline at end of file diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 7b63e8e86b..6f90af7ece 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -1896,6 +1896,7 @@ public: void debugDrawPose(controller::Action action, const char* channelName, float size); bool getIsJointOverridden(int jointIndex) const; + glm::vec3 getLookAtPivotPoint(); public slots: