From d80b52dc9f55b2fb1af5586a40fbd234de12317f Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 24 Feb 2014 11:33:52 -0800 Subject: [PATCH 1/2] Fixes for camera mode transitions, seeing inside head. --- interface/src/Application.cpp | 29 +++++++++++++++----------- interface/src/Application.h | 4 ++-- interface/src/Camera.cpp | 5 +++++ interface/src/Camera.h | 1 + interface/src/Menu.cpp | 6 ++---- interface/src/avatar/Avatar.cpp | 10 ++++----- interface/src/avatar/Avatar.h | 4 ++-- interface/src/avatar/AvatarManager.cpp | 10 ++++----- interface/src/avatar/AvatarManager.h | 2 +- interface/src/avatar/MyAvatar.cpp | 12 ++++------- interface/src/avatar/MyAvatar.h | 2 +- 11 files changed, 44 insertions(+), 41 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 38fee4baba..844ddaaee0 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1983,6 +1983,9 @@ void Application::updateMouseRay() { bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); PerformanceWarning warn(showWarnings, "Application::updateMouseRay()"); + // make sure the frustum is up-to-date + loadViewFrustum(_myCamera, _viewFrustum); + // if the mouse pointer isn't visible, act like it's at the center of the screen float x = 0.5f, y = 0.5f; if (!_mouseHidden) { @@ -2030,11 +2033,12 @@ void Application::updateVisage() { _visage.update(); } -void Application::updateMyAvatarLookAtPosition(glm::vec3& lookAtSpot) { +void Application::updateMyAvatarLookAtPosition() { bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); PerformanceWarning warn(showWarnings, "Application::updateMyAvatarLookAtPosition()"); + glm::vec3 lookAtSpot; if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { lookAtSpot = _myCamera.getPosition(); @@ -2223,21 +2227,22 @@ void Application::updateMetavoxels(float deltaTime) { } } -void Application::cameraMenuChanged() { +void Application::updateCameraMode() { + float modeShiftPeriod = (_myCamera.getMode() == CAMERA_MODE_MIRROR) ? 0.0f : 1.0f; if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) { if (_myCamera.getMode() != CAMERA_MODE_MIRROR) { _myCamera.setMode(CAMERA_MODE_MIRROR); - _myCamera.setModeShiftPeriod(0.00f); + _myCamera.setModeShiftPeriod(0.0f); } } else if (Menu::getInstance()->isOptionChecked(MenuOption::FirstPerson)) { if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON) { _myCamera.setMode(CAMERA_MODE_FIRST_PERSON); - _myCamera.setModeShiftPeriod(1.0f); + _myCamera.setModeShiftPeriod(modeShiftPeriod); } } else { if (_myCamera.getMode() != CAMERA_MODE_THIRD_PERSON) { _myCamera.setMode(CAMERA_MODE_THIRD_PERSON); - _myCamera.setModeShiftPeriod(1.0f); + _myCamera.setModeShiftPeriod(modeShiftPeriod); } } } @@ -2312,16 +2317,16 @@ void Application::update(float deltaTime) { bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); PerformanceWarning warn(showWarnings, "Application::update()"); + // lots of things depend on the camera mode, so get that first + updateCameraMode(); + // check what's under the mouse and update the mouse voxel updateMouseRay(); - // Set where I am looking based on my mouse ray (so that other people can see) - glm::vec3 lookAtSpot; - updateFaceshift(); updateVisage(); - _myAvatar->updateLookAtTargetAvatar(lookAtSpot); - updateMyAvatarLookAtPosition(lookAtSpot); + _myAvatar->updateLookAtTargetAvatar(); + updateMyAvatarLookAtPosition(); // Find the voxel we are hovering over, and respond if clicked float distance; @@ -2898,8 +2903,8 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { } } - bool renderMyHead = (whichCamera.getInterpolatedMode() != CAMERA_MODE_FIRST_PERSON); - _avatarManager.renderAvatars(renderMyHead, selfAvatarOnly); + bool forceRenderMyHead = (whichCamera.getInterpolatedMode() == CAMERA_MODE_MIRROR); + _avatarManager.renderAvatars(forceRenderMyHead, selfAvatarOnly); if (!selfAvatarOnly) { // Render the world box diff --git a/interface/src/Application.h b/interface/src/Application.h index ddd8d16c56..c1a96283a9 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -269,7 +269,6 @@ private slots: void setFullscreen(bool fullscreen); void setEnable3DTVMode(bool enable3DTVMode); - void cameraMenuChanged(); void renderThrustAtVoxel(const glm::vec3& thrust); @@ -307,7 +306,7 @@ private: void updateMouseRay(); void updateFaceshift(); void updateVisage(); - void updateMyAvatarLookAtPosition(glm::vec3& lookAtSpot); + void updateMyAvatarLookAtPosition(); void updateHoverVoxels(float deltaTime, float& distance, BoxFace& face); void updateMouseVoxels(float deltaTime, float& distance, BoxFace& face); void updateHandAndTouch(float deltaTime); @@ -316,6 +315,7 @@ private: void updateSerialDevices(float deltaTime); void updateThreads(float deltaTime); void updateMetavoxels(float deltaTime); + void updateCameraMode(); void updateCamera(float deltaTime); void updateDialogs(float deltaTime); void updateAudio(float deltaTime); diff --git a/interface/src/Camera.cpp b/interface/src/Camera.cpp index 8729ef58b6..be7e7bac50 100644 --- a/interface/src/Camera.cpp +++ b/interface/src/Camera.cpp @@ -123,6 +123,11 @@ void Camera::setModeShiftPeriod (float period) { const float MIN_PERIOD = 0.001f; const float MAX_PERIOD = 3.0f; _modeShiftPeriod = glm::clamp(period, MIN_PERIOD, MAX_PERIOD); + + // if a zero period was requested, we clearly want to snap immediately to the target + if (period == 0.0f) { + update(MIN_PERIOD); + } } void Camera::setMode(CameraMode m) { diff --git a/interface/src/Camera.h b/interface/src/Camera.h index 7b95ce97f1..b5bf6ea0b7 100644 --- a/interface/src/Camera.h +++ b/interface/src/Camera.h @@ -55,6 +55,7 @@ public: const glm::vec3& getPosition() const { return _position; } const glm::quat& getRotation() const { return _rotation; } CameraMode getMode() const { return _mode; } + float getModeShiftPeriod() const { return _modeShiftPeriod; } const glm::vec3& getTargetPosition() const { return _targetPosition; } const glm::quat& getTargetRotation() const { return _targetRotation; } float getFieldOfView() const { return _fieldOfView; } diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 7e5fe63524..1a7cbe5e6f 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -232,11 +232,9 @@ Menu::Menu() : false, appInstance, SLOT(setFullscreen(bool))); - addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FirstPerson, Qt::Key_P, true, - appInstance,SLOT(cameraMenuChanged())); + addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FirstPerson, Qt::Key_P, true); addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Mirror, Qt::SHIFT | Qt::Key_H, true); - addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FullscreenMirror, Qt::Key_H, false, - appInstance, SLOT(cameraMenuChanged())); + addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FullscreenMirror, Qt::Key_H, false); addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Enable3DTVMode, 0, false, diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index f0f950adc1..e2e364c616 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -187,7 +187,7 @@ static TextRenderer* textRenderer(TextRendererType type) { return displayNameRenderer; } -void Avatar::render(bool forceRenderHead) { +void Avatar::render() { glm::vec3 toTarget = _position - Application::getInstance()->getAvatar()->getPosition(); float lengthToTarget = glm::length(toTarget); @@ -205,7 +205,7 @@ void Avatar::render(bool forceRenderHead) { getHead()->getFaceModel().renderCollisionProxies(0.7f); } if (Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) { - renderBody(forceRenderHead); + renderBody(); } // render sphere when far away @@ -286,16 +286,14 @@ glm::quat Avatar::computeRotationFromBodyToWorldUp(float proportion) const { return glm::angleAxis(angle * proportion, axis); } -void Avatar::renderBody(bool forceRenderHead) { +void Avatar::renderBody() { const float BILLBOARD_DISTANCE = 40.0f; if (!_billboard.isEmpty() && getLODDistance() >= BILLBOARD_DISTANCE) { renderBillboard(); return; } _skeletonModel.render(1.0f); - if (forceRenderHead) { - getHead()->render(1.0f); - } + getHead()->render(1.0f); getHand()->render(false); } diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index b9433f15dc..be98254696 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -74,7 +74,7 @@ public: void init(); void simulate(float deltaTime); - void render(bool forceRenderHead); + void render(); //setters void setDisplayingLookatVectors(bool displayingLookatVectors) { getHead()->setRenderLookatVectors(displayingLookatVectors); } @@ -176,7 +176,7 @@ private: bool _initialized; QScopedPointer _billboardTexture; - void renderBody(bool forceRenderHead); + void renderBody(); void renderBillboard(); void renderDisplayName(); diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index f65566fe14..fed6716ffa 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -69,7 +69,7 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { simulateAvatarFades(deltaTime); } -void AvatarManager::renderAvatars(bool forceRenderHead, bool selfAvatarOnly) { +void AvatarManager::renderAvatars(bool forceRenderMyHead, bool selfAvatarOnly) { PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::renderAvatars()"); bool renderLookAtVectors = Menu::getInstance()->isOptionChecked(MenuOption::LookAtVectors); @@ -83,16 +83,16 @@ void AvatarManager::renderAvatars(bool forceRenderHead, bool selfAvatarOnly) { avatar->init(); } if (avatar == static_cast(_myAvatar.data())) { - avatar->render(forceRenderHead); + _myAvatar->render(forceRenderMyHead); } else { - avatar->render(true); + avatar->render(); } avatar->setDisplayingLookatVectors(renderLookAtVectors); } renderAvatarFades(); } else { // just render myAvatar - _myAvatar->render(forceRenderHead); + _myAvatar->render(forceRenderMyHead); _myAvatar->setDisplayingLookatVectors(renderLookAtVectors); } } @@ -121,7 +121,7 @@ void AvatarManager::renderAvatarFades() { foreach(const AvatarSharedPointer& fadingAvatar, _avatarFades) { Avatar* avatar = static_cast(fadingAvatar.data()); - avatar->render(false); + avatar->render(); } } diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h index 115423e618..24921f45dd 100644 --- a/interface/src/avatar/AvatarManager.h +++ b/interface/src/avatar/AvatarManager.h @@ -30,7 +30,7 @@ public: MyAvatar* getMyAvatar() { return _myAvatar.data(); } void updateOtherAvatars(float deltaTime); - void renderAvatars(bool forceRenderHead, bool selfAvatarOnly = false); + void renderAvatars(bool forceRenderMyHead, bool selfAvatarOnly = false); void clearOtherAvatars(); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 3bb156edcf..50b182c20c 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -669,7 +669,7 @@ void MyAvatar::orbit(const glm::vec3& position, int deltaX, int deltaY) { setPosition(position + rotation * (getPosition() - position)); } -void MyAvatar::updateLookAtTargetAvatar(glm::vec3 &eyePosition) { +void MyAvatar::updateLookAtTargetAvatar() { Application* applicationInstance = Application::getInstance(); if (!applicationInstance->isMousePressed()) { @@ -683,14 +683,9 @@ void MyAvatar::updateLookAtTargetAvatar(glm::vec3 &eyePosition) { } float distance; if (avatar->findRayIntersection(mouseOrigin, mouseDirection, distance)) { - // rescale to compensate for head embiggening - eyePosition = (avatar->getHead()->calculateAverageEyePosition() - avatar->getHead()->getScalePivot()) * - (avatar->getScale() / avatar->getHead()->getScale()) + avatar->getHead()->getScalePivot(); _lookAtTargetAvatar = avatarPointer; return; - } else { } - } _lookAtTargetAvatar.clear(); } @@ -724,9 +719,10 @@ void MyAvatar::renderBody(bool forceRenderHead) { _skeletonModel.render(1.0f); // Render head so long as the camera isn't inside it - const float RENDER_HEAD_CUTOFF_DISTANCE = 0.10f; + const float RENDER_HEAD_CUTOFF_DISTANCE = 0.40f; Camera* myCamera = Application::getInstance()->getCamera(); - if (forceRenderHead || (glm::length(myCamera->getPosition() - getHead()->calculateAverageEyePosition()) > RENDER_HEAD_CUTOFF_DISTANCE)) { + if (forceRenderHead || (glm::length(myCamera->getPosition() - getHead()->calculateAverageEyePosition()) > + RENDER_HEAD_CUTOFF_DISTANCE * _scale)) { getHead()->render(1.0f); } getHand()->render(true); diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 2b5be47419..2e80a9408d 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -81,7 +81,7 @@ public: void orbit(const glm::vec3& position, int deltaX, int deltaY); AvatarData* getLookAtTargetAvatar() const { return _lookAtTargetAvatar.data(); } - void updateLookAtTargetAvatar(glm::vec3& eyePosition); + void updateLookAtTargetAvatar(); void clearLookAtTargetAvatar(); virtual void setFaceModelURL(const QUrl& faceModelURL); From e40fe85c3651e5f93430cd0386360c3aec9e6715 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 24 Feb 2014 11:42:47 -0800 Subject: [PATCH 2/2] Updating the camera mode every frame screws with the scripts, so revert to updating it when the menu changes. --- interface/src/Application.cpp | 5 +---- interface/src/Application.h | 2 +- interface/src/Menu.cpp | 6 ++++-- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a08800d625..99e3f5be12 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2227,7 +2227,7 @@ void Application::updateMetavoxels(float deltaTime) { } } -void Application::updateCameraMode() { +void Application::cameraMenuChanged() { float modeShiftPeriod = (_myCamera.getMode() == CAMERA_MODE_MIRROR) ? 0.0f : 1.0f; if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) { if (_myCamera.getMode() != CAMERA_MODE_MIRROR) { @@ -2317,9 +2317,6 @@ void Application::update(float deltaTime) { bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); PerformanceWarning warn(showWarnings, "Application::update()"); - // lots of things depend on the camera mode, so get that first - updateCameraMode(); - // check what's under the mouse and update the mouse voxel updateMouseRay(); diff --git a/interface/src/Application.h b/interface/src/Application.h index c1a96283a9..f3f4f3dbb2 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -269,6 +269,7 @@ private slots: void setFullscreen(bool fullscreen); void setEnable3DTVMode(bool enable3DTVMode); + void cameraMenuChanged(); void renderThrustAtVoxel(const glm::vec3& thrust); @@ -315,7 +316,6 @@ private: void updateSerialDevices(float deltaTime); void updateThreads(float deltaTime); void updateMetavoxels(float deltaTime); - void updateCameraMode(); void updateCamera(float deltaTime); void updateDialogs(float deltaTime); void updateAudio(float deltaTime); diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 1a7cbe5e6f..7e5fe63524 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -232,9 +232,11 @@ Menu::Menu() : false, appInstance, SLOT(setFullscreen(bool))); - addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FirstPerson, Qt::Key_P, true); + addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FirstPerson, Qt::Key_P, true, + appInstance,SLOT(cameraMenuChanged())); addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Mirror, Qt::SHIFT | Qt::Key_H, true); - addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FullscreenMirror, Qt::Key_H, false); + addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FullscreenMirror, Qt::Key_H, false, + appInstance, SLOT(cameraMenuChanged())); addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Enable3DTVMode, 0, false,