Showing the changes to interface/src/Application.cpp (1 of 8 files). Show all
Unified · Split
| @@ -2133,10 +2133,12 @@ void Application::updateCursor(float deltaTime) { · 2132 unmodified lines | ||
| 2133 | 2133 | } |
| 2134 | 2134 | |
| 2135 | 2135 | void Application::updateCursorVisibility() { |
| 2136 | − if (!_cursorVisible || Menu::getInstance()->isOptionChecked(MenuOption::EnableVRMode)) { | |
| 2137 | − _glWidget->setCursor(Qt::BlankCursor); | |
| 2136 | + if (!_cursorVisible || | |
| 2137 | + Menu::getInstance()->isOptionChecked(MenuOption::EnableVRMode) || | |
| 2138 | + Menu::getInstance()->isOptionChecked(MenuOption::Enable3DTVMode)) { | |
| 2139 | + _window->setCursor(Qt::BlankCursor); | |
| 2138 | 2140 | } else { |
| 2139 | − _glWidget->unsetCursor(); | |
| 2141 | + _window->unsetCursor(); | |
| 2140 | 2142 | } |
| 2141 | 2143 | } |
| 2142 | 2144 | |
| @@ -2789,7 +2791,27 @@ QImage Application::renderAvatarBillboard() { · 646 unmodified lines | ||
| 2789 | 2791 | return image; |
| 2790 | 2792 | } |
| 2791 | 2793 | |
| 2794 | +// FIXME, preprocessor guard this check to occur only in DEBUG builds | |
| 2795 | +static QThread * activeRenderingThread = nullptr; | |
| 2796 | + | |
| 2797 | +ViewFrustum* Application::getViewFrustum() { | |
| 2798 | + if (QThread::currentThread() == activeRenderingThread) { | |
| 2799 | + // FIXME, should this be an assert? | |
| 2800 | + qWarning() << "Calling Application::getViewFrustum() from the active rendering thread, did you mean Application::getDisplayViewFrustum()?"; | |
| 2801 | + } | |
| 2802 | + return &_viewFrustum; | |
| 2803 | +} | |
| 2804 | + | |
| 2805 | +ViewFrustum* Application::getDisplayViewFrustum() { | |
| 2806 | + if (QThread::currentThread() != activeRenderingThread) { | |
| 2807 | + // FIXME, should this be an assert? | |
| 2808 | + qWarning() << "Calling Application::getDisplayViewFrustum() from outside the active rendering thread or outside rendering, did you mean Application::getViewFrustum()?"; | |
| 2809 | + } | |
| 2810 | + return &_displayViewFrustum; | |
| 2811 | +} | |
| 2812 | + | |
| 2792 | 2813 | void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs::RenderSide renderSide) { |
| 2814 | + activeRenderingThread = QThread::currentThread(); | |
| 2793 | 2815 | PROFILE_RANGE(__FUNCTION__); |
| 2794 | 2816 | PerformanceTimer perfTimer("display"); |
| 2795 | 2817 | PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide()"); |
| @@ -3014,6 +3036,7 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs · 218 unmodified lines | ||
| 3014 | 3036 | glClear(GL_DEPTH_BUFFER_BIT); |
| 3015 | 3037 | _overlays.renderWorld(true); |
| 3016 | 3038 | } |
| 3039 | + activeRenderingThread = nullptr; | |
| 3017 | 3040 | } |
| 3018 | 3041 | |
| 3019 | 3042 | void Application::updateUntranslatedViewMatrix(const glm::vec3& viewMatrixTranslation) { |
| @@ -3106,17 +3129,25 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) { · 86 unmodified lines | ||
| 3106 | 3129 | _myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_BODY_DISTANCE * _myAvatar->getScale()); |
| 3107 | 3130 | |
| 3108 | 3131 | } else { // HEAD zoom level |
| 3132 | + // FIXME note that the positioing of the camera relative to the avatar can suffer limited | |
| 3133 | + // precision as the user's position moves further away from the origin. Thus at | |
| 3134 | + // /1e7,1e7,1e7 (well outside the buildable volume) the mirror camera veers and sways | |
| 3135 | + // wildly as you rotate your avatar because the floating point values are becoming | |
| 3136 | + // larger, squeezing out the available digits of precision you have available at the | |
| 3137 | + // human scale for camera positioning. | |
| 3138 | + | |
| 3139 | + // Previously there was a hack to correct this using the mechanism of repositioning | |
| 3140 | + // the avatar at the origin of the world for the purposes of rendering the mirror, | |
| 3141 | + // but it resulted in failing to render the avatar's head model in the mirror view | |
| 3142 | + // when in first person mode. Presumably this was because of some missed culling logic | |
| 3143 | + // that was not accounted for in the hack. | |
| 3144 | + | |
| 3145 | + // This was removed in commit 71e59cfa88c6563749594e25494102fe01db38e9 but could be further | |
| 3146 | + // investigated in order to adapt the technique while fixing the head rendering issue, | |
| 3147 | + // but the complexity of the hack suggests that a better approach | |
| 3109 | 3148 | _mirrorCamera.setFieldOfView(MIRROR_FIELD_OF_VIEW); // degrees |
| 3110 | − if (_myAvatar->getSkeletonModel().isActive() && _myAvatar->getHead()->getFaceModel().isActive()) { | |
| 3111 | − // as a hack until we have a better way of dealing with coordinate precision issues, reposition the | |
| 3112 | − // face/body so that the average eye position lies at the origin | |
| 3113 | − eyeRelativeCamera = true; | |
| 3114 | − _mirrorCamera.setPosition(_myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_DISTANCE * _myAvatar->getScale()); | |
| 3115 | − | |
| 3116 | − } else { | |
| 3117 | − _mirrorCamera.setPosition(_myAvatar->getHead()->getEyePosition() + | |
| 3118 | − _myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_DISTANCE * _myAvatar->getScale()); | |
| 3119 | − } | |
| 3149 | + _mirrorCamera.setPosition(_myAvatar->getHead()->getEyePosition() + | |
| 3150 | + _myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_DISTANCE * _myAvatar->getScale()); | |
| 3120 | 3151 | } |
| 3121 | 3152 | _mirrorCamera.setAspectRatio((float)region.width() / region.height()); |
| 3122 | 3153 | |
| @@ -3143,58 +3174,7 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) { · 20 unmodified lines | ||
| 3143 | 3174 | |
| 3144 | 3175 | // render rear mirror view |
| 3145 | 3176 | glPushMatrix(); |
| 3146 | − if (eyeRelativeCamera) { | |
| 3147 | − // save absolute translations | |
| 3148 | − glm::vec3 absoluteSkeletonTranslation = _myAvatar->getSkeletonModel().getTranslation(); | |
| 3149 | − glm::vec3 absoluteFaceTranslation = _myAvatar->getHead()->getFaceModel().getTranslation(); | |
| 3150 | − | |
| 3151 | − // get the neck position so we can translate the face relative to it | |
| 3152 | − glm::vec3 neckPosition; | |
| 3153 | − _myAvatar->getSkeletonModel().setTranslation(glm::vec3()); | |
| 3154 | − _myAvatar->getSkeletonModel().getNeckPosition(neckPosition); | |
| 3155 | − | |
| 3156 | − // get the eye position relative to the body | |
| 3157 | − glm::vec3 eyePosition = _myAvatar->getHead()->getEyePosition(); | |
| 3158 | − float eyeHeight = eyePosition.y - _myAvatar->getPosition().y; | |
| 3159 | − | |
| 3160 | − // set the translation of the face relative to the neck position | |
| 3161 | − _myAvatar->getHead()->getFaceModel().setTranslation(neckPosition - glm::vec3(0, eyeHeight, 0)); | |
| 3162 | − | |
| 3163 | − // translate the neck relative to the face | |
| 3164 | − _myAvatar->getSkeletonModel().setTranslation(_myAvatar->getHead()->getFaceModel().getTranslation() - | |
| 3165 | − neckPosition); | |
| 3166 | − | |
| 3167 | − // update the attachments to match | |
| 3168 | − QVector<glm::vec3> absoluteAttachmentTranslations; | |
| 3169 | − glm::vec3 delta = _myAvatar->getSkeletonModel().getTranslation() - absoluteSkeletonTranslation; | |
| 3170 | − foreach (Model* attachment, _myAvatar->getAttachmentModels()) { | |
| 3171 | − absoluteAttachmentTranslations.append(attachment->getTranslation()); | |
| 3172 | − attachment->setTranslation(attachment->getTranslation() + delta); | |
| 3173 | − } | |
| 3174 | − | |
| 3175 | − // and lo, even the shadow matrices | |
| 3176 | − glm::mat4 savedShadowMatrices[CASCADED_SHADOW_MATRIX_COUNT]; | |
| 3177 | − for (int i = 0; i < CASCADED_SHADOW_MATRIX_COUNT; i++) { | |
| 3178 | − savedShadowMatrices[i] = _shadowMatrices[i]; | |
| 3179 | − _shadowMatrices[i] = glm::transpose(glm::transpose(_shadowMatrices[i]) * glm::translate(-delta)); | |
| 3180 | − } | |
| 3181 | − | |
| 3182 | − displaySide(_mirrorCamera, true); | |
| 3183 | − | |
| 3184 | − // restore absolute translations | |
| 3185 | − _myAvatar->getSkeletonModel().setTranslation(absoluteSkeletonTranslation); | |
| 3186 | − _myAvatar->getHead()->getFaceModel().setTranslation(absoluteFaceTranslation); | |
| 3187 | − for (int i = 0; i < absoluteAttachmentTranslations.size(); i++) { | |
| 3188 | − _myAvatar->getAttachmentModels().at(i)->setTranslation(absoluteAttachmentTranslations.at(i)); | |
| 3189 | − } | |
| 3190 | − | |
| 3191 | − // restore the shadow matrices | |
| 3192 | − for (int i = 0; i < CASCADED_SHADOW_MATRIX_COUNT; i++) { | |
| 3193 | − _shadowMatrices[i] = savedShadowMatrices[i]; | |
| 3194 | − } | |
| 3195 | − } else { | |
| 3196 | − displaySide(_mirrorCamera, true); | |
| 3197 | − } | |
| 3177 | + displaySide(_mirrorCamera, true); | |
| 3198 | 3178 | glPopMatrix(); |
| 3199 | 3179 | |
| 3200 | 3180 | if (!billboard) { |