From 71e59cfa88c6563749594e25494102fe01db38e9 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 17 Mar 2015 13:15:15 -0700 Subject: [PATCH 1/2] Fix: Mini-mirror doesn't render avatar head when in first person mode --- interface/src/Application.cpp | 65 ++--------------------------------- 1 file changed, 3 insertions(+), 62 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 184d1bf940..fc9e5c101b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3113,16 +3113,8 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) { } else { // HEAD zoom level _mirrorCamera.setFieldOfView(MIRROR_FIELD_OF_VIEW); // degrees - if (_myAvatar->getSkeletonModel().isActive() && _myAvatar->getHead()->getFaceModel().isActive()) { - // as a hack until we have a better way of dealing with coordinate precision issues, reposition the - // face/body so that the average eye position lies at the origin - eyeRelativeCamera = true; - _mirrorCamera.setPosition(_myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_DISTANCE * _myAvatar->getScale()); - - } else { - _mirrorCamera.setPosition(_myAvatar->getHead()->getEyePosition() + - _myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_DISTANCE * _myAvatar->getScale()); - } + _mirrorCamera.setPosition(_myAvatar->getHead()->getEyePosition() + + _myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_DISTANCE * _myAvatar->getScale()); } _mirrorCamera.setAspectRatio((float)region.width() / region.height()); @@ -3149,58 +3141,7 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) { // render rear mirror view glPushMatrix(); - if (eyeRelativeCamera) { - // save absolute translations - glm::vec3 absoluteSkeletonTranslation = _myAvatar->getSkeletonModel().getTranslation(); - glm::vec3 absoluteFaceTranslation = _myAvatar->getHead()->getFaceModel().getTranslation(); - - // get the neck position so we can translate the face relative to it - glm::vec3 neckPosition; - _myAvatar->getSkeletonModel().setTranslation(glm::vec3()); - _myAvatar->getSkeletonModel().getNeckPosition(neckPosition); - - // get the eye position relative to the body - glm::vec3 eyePosition = _myAvatar->getHead()->getEyePosition(); - float eyeHeight = eyePosition.y - _myAvatar->getPosition().y; - - // set the translation of the face relative to the neck position - _myAvatar->getHead()->getFaceModel().setTranslation(neckPosition - glm::vec3(0, eyeHeight, 0)); - - // translate the neck relative to the face - _myAvatar->getSkeletonModel().setTranslation(_myAvatar->getHead()->getFaceModel().getTranslation() - - neckPosition); - - // update the attachments to match - QVector absoluteAttachmentTranslations; - glm::vec3 delta = _myAvatar->getSkeletonModel().getTranslation() - absoluteSkeletonTranslation; - foreach (Model* attachment, _myAvatar->getAttachmentModels()) { - absoluteAttachmentTranslations.append(attachment->getTranslation()); - attachment->setTranslation(attachment->getTranslation() + delta); - } - - // and lo, even the shadow matrices - glm::mat4 savedShadowMatrices[CASCADED_SHADOW_MATRIX_COUNT]; - for (int i = 0; i < CASCADED_SHADOW_MATRIX_COUNT; i++) { - savedShadowMatrices[i] = _shadowMatrices[i]; - _shadowMatrices[i] = glm::transpose(glm::transpose(_shadowMatrices[i]) * glm::translate(-delta)); - } - - displaySide(_mirrorCamera, true); - - // restore absolute translations - _myAvatar->getSkeletonModel().setTranslation(absoluteSkeletonTranslation); - _myAvatar->getHead()->getFaceModel().setTranslation(absoluteFaceTranslation); - for (int i = 0; i < absoluteAttachmentTranslations.size(); i++) { - _myAvatar->getAttachmentModels().at(i)->setTranslation(absoluteAttachmentTranslations.at(i)); - } - - // restore the shadow matrices - for (int i = 0; i < CASCADED_SHADOW_MATRIX_COUNT; i++) { - _shadowMatrices[i] = savedShadowMatrices[i]; - } - } else { - displaySide(_mirrorCamera, true); - } + displaySide(_mirrorCamera, true); glPopMatrix(); if (!billboard) { From c88f6f8f0718c143bab0dcb02788de6e09143ab9 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 17 Mar 2015 13:49:06 -0700 Subject: [PATCH 2/2] Adding some documentation on the change --- interface/src/Application.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index fc9e5c101b..571cf493bd 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3112,6 +3112,22 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) { _myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_BODY_DISTANCE * _myAvatar->getScale()); } else { // HEAD zoom level + // FIXME note that the positioing of the camera relative to the avatar can suffer limited + // precision as the user's position moves further away from the origin. Thus at + // /1e7,1e7,1e7 (well outside the buildable volume) the mirror camera veers and sways + // wildly as you rotate your avatar because the floating point values are becoming + // larger, squeezing out the available digits of precision you have available at the + // human scale for camera positioning. + + // Previously there was a hack to correct this using the mechanism of repositioning + // the avatar at the origin of the world for the purposes of rendering the mirror, + // but it resulted in failing to render the avatar's head model in the mirror view + // when in first person mode. Presumably this was because of some missed culling logic + // that was not accounted for in the hack. + + // This was removed in commit 71e59cfa88c6563749594e25494102fe01db38e9 but could be further + // investigated in order to adapt the technique while fixing the head rendering issue, + // but the complexity of the hack suggests that a better approach _mirrorCamera.setFieldOfView(MIRROR_FIELD_OF_VIEW); // degrees _mirrorCamera.setPosition(_myAvatar->getHead()->getEyePosition() + _myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_DISTANCE * _myAvatar->getScale());